Beispiel #1
0
    def from_conf(conf, options):
        import sfepy
        from sfepy.discrete.fem import Mesh, FEDomain, Field
        mesh = Mesh.from_file('meshes/2d/rectangle_tri.mesh',
                              prefix_dir=sfepy.data_dir)
        domain = FEDomain('domain', mesh)
        dim = domain.shape.dim

        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',
                                      'vertices in x < %.10f' % (min_x + eps),
                                      'facet')
        gamma2 = domain.create_region('Gamma2',
                                      'vertices in x > %.10f' % (max_x - eps),
                                      'facet')

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

        test = Test(conf=conf, options=options, dim=dim,
                    omega=omega, gamma1=gamma1, gamma2=gamma2,
                    field=field)
        return test
Beispiel #2
0
def _get_bqp(geometry, order):
    from sfepy.discrete import Integral
    from sfepy.discrete.fem.geometry_element import GeometryElement
    from sfepy.discrete.fem import Mesh, FEDomain, Field

    gel = GeometryElement(geometry)

    mesh = Mesh.from_data('aux', gel.coors, None,
                          [gel.conn[None, :]], [[0]], [geometry])
    domain = FEDomain('domain', mesh)
    omega = domain.create_region('Omega', 'all')
    surf =  domain.create_region('Surf', 'vertices of surface', 'facet')
    field = Field.from_args('f', nm.float64, shape=1,
                            region=omega, approx_order=1)
    field.setup_surface_data(surf)

    integral = Integral('aux', order=order)
    field.create_bqp('Surf', integral)

    sd = field.surface_data['Surf']
    qp = field.qp_coors[(integral.order, sd.bkey)]

    output('geometry:', geometry, 'order:', order, 'num. points:',
           qp.vals.shape[1], 'true_order:',
           integral.qps[gel.surface_facet_name].order)
    output('min. weight:', qp.weights.min())
    output('max. weight:', qp.weights.max())

    return (gel, qp.vals.reshape((-1, mesh.dim)),
            nm.tile(qp.weights, qp.vals.shape[0]))
Beispiel #3
0
    def test_entity_volumes(self):
        import sfepy
        from sfepy.discrete.fem import Mesh, FEDomain
        from sfepy.discrete.common import Field
        from sfepy.discrete import Integral

        mesh = Mesh.from_file('meshes/3d/special/cross3d.mesh',
                              prefix_dir=sfepy.data_dir)
        domain = FEDomain('domain', mesh)

        omega = domain.create_region('Omega', 'all')
        gamma = domain.create_region('Gamma', 'vertices of surface', 'facet')
        top = domain.create_region('Top', 'cell 2')

        vfield = Field.from_args('v', nm.float64, 'scalar', omega,
                                 approx_order=1)
        sfield = Field.from_args('s', nm.float64, 'scalar', gamma,
                                 approx_order=1)

        integral = Integral('i', order=3)
        vgeo, _ = vfield.get_mapping(omega, integral, 'volume')
        domain.create_surface_group(gamma)
        sgeo, _ = sfield.get_mapping(gamma, integral, 'surface')

        evols = mesh.cmesh.get_volumes(1)
        fvols = mesh.cmesh.get_volumes(2) # Approximate for non-planar faces.
        cvols = mesh.cmesh.get_volumes(3)

        ok = True
        _ok = abs(cvols.sum() - vgeo.volume.sum()) < 1e-15
        self.report('total cell volume: %s (ok: %s)' % (cvols.sum(), _ok))
        ok = _ok and ok

        top_evols = nm.array([ 1.                ,  1.                ,
                               1.                ,  1.                ,
                               0.7211102550927979,  0.7211102550927979,
                               0.7211102550927979,  0.7211102550927979,
                               1.16619037896906  ,  1.16619037896906  ,
                               1.16619037896906  ,  1.16619037896906  ])

        _ok = nm.allclose(top_evols, evols[top.edges], rtol=0.0, atol=1e-15)
        self.report('total top cell edge length: %s (ok: %s)'
                    % (evols[top.edges].sum(), _ok))
        ok = _ok and ok

        i1 = [5, 6, 8, 9]
        i2 = nm.setdiff1d(nm.arange(len(gamma.faces)), i1)
        aux = fvols[gamma.faces] - sgeo.volume.ravel()

        _ok = nm.allclose(aux[i1], 0.10560208437556773, rtol=0.0, atol=1e-15)
        ok = _ok and ok
        self.report('non-planar faces diff: %s (ok: %s)' % (aux[i1], _ok))

        _ok = (nm.abs(aux[i2]) < 1e-15).all()
        self.report('max. planar faces diff: %s (ok: %s)'
                    % (nm.abs(aux[i2]).max(), _ok))
        ok = _ok and ok

        return ok
Beispiel #4
0
    def test_interpolation_two_meshes(self):
        from sfepy import data_dir
        from sfepy.discrete import Variables
        from sfepy.discrete.fem import Mesh, FEDomain, Field

        m1 = Mesh.from_file(data_dir + '/meshes/3d/block.mesh')

        m2 = Mesh.from_file(data_dir + '/meshes/3d/cube_medium_tetra.mesh')
        m2.coors[:] *= 2.0

        bbox = m1.get_bounding_box()
        dd = bbox[1,:] - bbox[0,:]
        data = nm.sin(4.0 * nm.pi * m1.coors[:,0:1] / dd[0]) \
               * nm.cos(4.0 * nm.pi * m1.coors[:,1:2] / dd[1])

        variables1 = {
            'u'       : ('unknown field', 'scalar_tp', 0),
            'v'       : ('test field',    'scalar_tp', 'u'),
        }

        variables2 = {
            'u'       : ('unknown field', 'scalar_si', 0),
            'v'       : ('test field',    'scalar_si', 'u'),
        }

        d1 = FEDomain('d1', m1)
        omega1 = d1.create_region('Omega', 'all')
        field1 = Field.from_args('scalar_tp', nm.float64, (1,1), omega1,
                                 approx_order=1)
        ff1 = {field1.name : field1}

        d2 = FEDomain('d2', m2)
        omega2 = d2.create_region('Omega', 'all')
        field2 = Field.from_args('scalar_si', nm.float64, (1,1), omega2,
                                 approx_order=0)
        ff2 = {field2.name : field2}

        vv1 = Variables.from_conf(transform_variables(variables1), ff1)
        u1 = vv1['u']
        u1.set_from_mesh_vertices(data)

        vv2 = Variables.from_conf(transform_variables(variables2), ff2)
        u2 = vv2['u']

        # Performs interpolation, if other field differs from self.field
        # or, in particular, is defined on a different mesh.
        u2.set_from_other(u1, strategy='interpolation', close_limit=0.1)

        fname = in_dir(self.options.out_dir)
        u1.save_as_mesh(fname('test_mesh_interp_block_scalar.vtk'))
        u2.save_as_mesh(fname('test_mesh_interp_cube_scalar.vtk'))

        return True
Beispiel #5
0
    def test_evaluate_at(self):
        from sfepy import data_dir
        from sfepy.discrete.fem import Mesh
        from sfepy.discrete import Variables
        from sfepy.discrete.fem import FEDomain, Field

        meshes = {
            'tp' : Mesh.from_file(data_dir + '/meshes/3d/block.mesh'),
        }
        datas = gen_datas(meshes)

        fields = {
            'scalar_tp' : ((1,1), 'Omega', 1),
            'vector_tp' : ((3,1), 'Omega', 1),
        }

        ok = True
        for field_name in ['scalar_tp', 'vector_tp']:
            d = FEDomain('d', meshes['tp'])
            d.create_region('Omega', 'all')

            f = fields[field_name]
            field = Field.from_args('f', nm.complex128, f[0],
                                    d.regions[f[1]],
                                    approx_order=f[2])
            ff = {field.name : field}

            vv = Variables.from_conf(transform_variables(variables), ff)
            u = vv['u']

            bbox = d.get_mesh_bounding_box()
            t = nm.expand_dims(nm.linspace(0, 1, 100), 1)
            coors = nm.expand_dims(bbox[1] - bbox[0], 0) * t + bbox[0]

            data_r = datas[field_name]
            data_i = 2. / (1 + datas[field_name])

            u.set_from_mesh_vertices(data_r)
            vals_r = u.evaluate_at(coors)
            u.set_from_mesh_vertices(data_i)
            vals_i = u.evaluate_at(coors)
            u.set_from_mesh_vertices(data_r + data_i * 1j)
            vals = u.evaluate_at(coors)

            _ok = nm.allclose(vals_r + vals_i * 1j, vals, rtol=0.0, atol=1e-12)
            _ok = _ok and nm.abs(vals).sum() > 1
            self.report('evaluating complex field %s: %s' % (field_name, _ok))

            ok = ok and _ok

        return ok
def make_domain(dims, shape, transform=None):
    """
    Generate a 2D rectangle domain in 3D space, define regions.
    """
    xmin = (-0.5 + 1e-12) * dims[0]
    xmax = (0.5 - 1e-12) * dims[0]

    mesh = make_mesh(dims, shape, transform=transform)
    domain = FEDomain('domain', mesh)
    domain.create_region('Omega', 'all')
    domain.create_region('Gamma1', 'vertices in (x < %.14f)' % xmin, 'facet')
    domain.create_region('Gamma2', 'vertices in (x > %.14f)' % xmax, 'facet')

    return domain
Beispiel #7
0
def do_interpolation(m2, m1, data, field_name, force=False):
    """Interpolate data from m1 to m2. """
    from sfepy.discrete import Variables
    from sfepy.discrete.fem import FEDomain, Field

    fields = {
        'scalar_si' : ((1,1), 'Omega', 2),
        'vector_si' : ((3,1), 'Omega', 2),
        'scalar_tp' : ((1,1), 'Omega', 1),
        'vector_tp' : ((3,1), 'Omega', 1),
    }

    d1 = FEDomain('d1', m1)

    omega1 = d1.create_region('Omega', 'all')

    f = fields[field_name]

    field1 = Field.from_args('f', nm.float64, f[0], d1.regions[f[1]],
                             approx_order=f[2])
    ff = {field1.name : field1}

    vv = Variables.from_conf(transform_variables(variables), ff)
    u1 = vv['u']
    u1.set_from_mesh_vertices(data)

    d2 = FEDomain('d2', m2)
    omega2 = d2.create_region('Omega', 'all')

    field2 = Field.from_args('f', nm.float64, f[0], d2.regions[f[1]],
                             approx_order=f[2])
    ff2 = {field2.name : field2}

    vv2 = Variables.from_conf(transform_variables(variables), ff2)
    u2 = vv2['u']

    if not force:
        # Performs interpolation, if other field differs from self.field
        # or, in particular, is defined on a different mesh.
        u2.set_from_other(u1, strategy='interpolation', close_limit=0.5)

    else:
        coors = u2.field.get_coor()
        vals = u1.evaluate_at(coors, close_limit=0.5)
        u2.set_data(vals)

    return u1, u2
Beispiel #8
0
def main():
    parser = ArgumentParser(description=__doc__.rstrip(),
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('filename', help=helps['filename'])
    parser.add_argument('-d', '--detailed',
                        action='store_true', dest='detailed',
                        default=False, help=helps['detailed'])
    options = parser.parse_args()

    mesh = Mesh.from_file(options.filename)

    output(mesh.cmesh)
    output('element types:', mesh.descs)
    output('nodal BCs:', sorted(mesh.nodal_bcs.keys()))

    bbox = mesh.get_bounding_box()
    output('bounding box:\n%s'
           % '\n'.join('%s: [%14.7e, %14.7e]' % (name, bbox[0, ii], bbox[1, ii])
                       for ii, name in enumerate('xyz'[:mesh.dim])))

    output('centre:           [%s]'
           % ', '.join('%14.7e' % ii for ii in 0.5 * (bbox[0] + bbox[1])))
    output('coordinates mean: [%s]'
           % ', '.join('%14.7e' % ii for ii in mesh.coors.mean(0)))

    if not options.detailed: return

    domain = FEDomain(mesh.name, mesh)

    for dim in range(1, mesh.cmesh.tdim + 1):
        volumes = mesh.cmesh.get_volumes(dim)
        output('volumes of %d %dD entities:\nmin: %.7e mean: %.7e median:'
               ' %.7e max: %.7e'
               % (mesh.cmesh.num[dim], dim, volumes.min(), volumes.mean(),
                  nm.median(volumes), volumes.max()))

    euler = lambda mesh: nm.dot(mesh.cmesh.num, [1, -1, 1, -1])
    ec = euler(mesh)
    output('Euler characteristic:', ec)

    graph = mesh.create_conn_graph(verbose=False)
    n_comp, _ = graph_components(graph.shape[0], graph.indptr, graph.indices)
    output('number of connected components:', n_comp)

    if mesh.dim > 1:
        region = domain.create_region('surf', 'vertices of surface', 'facet')
        surf_mesh = Mesh.from_region(region, mesh,
                                     localize=True, is_surface=True)
        FEDomain(surf_mesh.name, surf_mesh) # Calls CMesh.setup_entities().

        sec = euler(surf_mesh)
        output('surface Euler characteristic:', sec)
        if mesh.dim == 3:
            output('surface genus:', (2.0 - sec) / 2.0)

        surf_graph = surf_mesh.create_conn_graph(verbose=False)
        n_comp, _ = graph_components(surf_graph.shape[0],
                                     surf_graph.indptr, surf_graph.indices)
        output('number of connected surface components:', n_comp)
Beispiel #9
0
    def test_projection_iga_fem(self):
        from sfepy.discrete import FieldVariable
        from sfepy.discrete.fem import FEDomain, Field
        from sfepy.discrete.iga.domain import IGDomain
        from sfepy.mesh.mesh_generators import gen_block_mesh
        from sfepy.discrete.iga.domain_generators import gen_patch_block_domain
        from sfepy.discrete.projections import (make_l2_projection,
                                                make_l2_projection_data)

        shape = [10, 12, 12]
        dims = [5, 6, 6]
        centre = [0, 0, 0]
        degrees = [2, 2, 2]

        nurbs, bmesh, regions = gen_patch_block_domain(dims, shape, centre,
                                                       degrees,
                                                       cp_mode='greville',
                                                       name='iga')
        ig_domain = IGDomain('iga', nurbs, bmesh, regions=regions)

        ig_omega = ig_domain.create_region('Omega', 'all')
        ig_field = Field.from_args('iga', nm.float64, 1, ig_omega,
                                   approx_order='iga', poly_space_base='iga')
        ig_u = FieldVariable('ig_u', 'parameter', ig_field,
                             primary_var_name='(set-to-None)')

        mesh = gen_block_mesh(dims, shape, centre, name='fem')
        fe_domain = FEDomain('fem', mesh)

        fe_omega = fe_domain.create_region('Omega', 'all')
        fe_field = Field.from_args('fem', nm.float64, 1, fe_omega,
                                   approx_order=2)
        fe_u = FieldVariable('fe_u', 'parameter', fe_field,
                             primary_var_name='(set-to-None)')

        def _eval_data(ts, coors, mode, **kwargs):
            return nm.prod(coors**2, axis=1)[:, None, None]

        make_l2_projection_data(ig_u, _eval_data)

        make_l2_projection(fe_u, ig_u) # This calls ig_u.evaluate_at().

        coors = 0.5 * nm.random.rand(20, 3) * dims

        ig_vals = ig_u.evaluate_at(coors)
        fe_vals = fe_u.evaluate_at(coors)

        ok = nm.allclose(ig_vals, fe_vals, rtol=0.0, atol=1e-12)
        if not ok:
            self.report('iga-fem projection failed!')
            self.report('coors:')
            self.report(coors)
            self.report('iga fem diff:')
            self.report(nm.c_[ig_vals, fe_vals, nm.abs(ig_vals - fe_vals)])

        return ok
Beispiel #10
0
    def from_conf(conf, options):
        from sfepy.discrete import Integral
        from sfepy.discrete.fem import Mesh, FEDomain

        domains = []
        for filename in filename_meshes:
            mesh = Mesh.from_file(filename)
            domain = FEDomain('domain_%s' % mesh.name.replace(data_dir, ''),
                              mesh)
            domain.create_region('Omega', 'all')
            domain.create_region('Gamma', 'vertices of surface', 'facet')

            domains.append(domain)

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

        test = Test(domains=domains, integral=integral,
                    conf=conf, options=options)
        return test
Beispiel #11
0
    def from_conf(conf, options):
        mesh = Mesh.from_file('meshes/2d/square_unit_tri.mesh',
                              prefix_dir=sfepy.data_dir)
        domain = FEDomain('domain', mesh)

        omega = domain.create_region('Omega', 'all')

        field = Field.from_args('linear', nm.float64, 'scalar', omega,
                                approx_order=1)

        test = Test(conf=conf, options=options, omega=omega, field=field)
        return test
Beispiel #12
0
    def test_normals(self):
        """
        Check orientations of surface normals on the reference elements.
        """
        import sfepy
        from sfepy.discrete import Integral
        from sfepy.discrete.fem import Mesh, FEDomain
        from sfepy.discrete.fem.poly_spaces import PolySpace
        from sfepy.discrete.fem.mappings import SurfaceMapping
        from sfepy.linalg import normalize_vectors

        ok = True

        for geom in ['2_3', '2_4', '3_4', '3_8']:
            mesh = Mesh.from_file('meshes/elements/%s_1.mesh' % geom,
                                  prefix_dir=sfepy.data_dir)
            domain = FEDomain('domain', mesh)
            surface = domain.create_region('Surface', 'vertices of surface',
                                           'facet')
            domain.create_surface_group(surface)

            sd = domain.surface_groups[surface.name]

            coors = domain.get_mesh_coors()
            gel = domain.geom_els[geom].surface_facet
            ps = PolySpace.any_from_args('aux', gel, 1)

            mapping = SurfaceMapping(coors, sd.get_connectivity(), ps)

            integral = Integral('i', order=1)
            vals, weights = integral.get_qp(gel.name)

            # Evaluate just in the first quadrature point...
            geo = mapping.get_mapping(vals[:1], weights[:1])

            expected = expected_normals[geom].copy()
            normalize_vectors(expected)

            _ok = nm.allclose(expected, geo.normal[:, 0, :, 0],
                              rtol=0.0, atol=1e-14)
            self.report('%s: %s' % (geom, _ok))

            if not _ok:
                self.report('expected:')
                self.report(expected)
                self.report('actual:')
                self.report(geo.normal[:, 0, :, 0])

            ok = ok and _ok

        return ok
Beispiel #13
0
    def test_invariance_qp(self):
        from sfepy import data_dir
        from sfepy.discrete import Variables, Integral
        from sfepy.discrete.fem import Mesh, FEDomain, Field
        from sfepy.terms import Term
        from sfepy.discrete.common.mappings import get_physical_qps

        mesh = Mesh.from_file(data_dir + '/meshes/3d/block.mesh')

        bbox = mesh.get_bounding_box()
        dd = bbox[1,:] - bbox[0,:]
        data = nm.sin(4.0 * nm.pi * mesh.coors[:,0:1] / dd[0]) \
               * nm.cos(4.0 * nm.pi * mesh.coors[:,1:2] / dd[1])

        variables = {
            'u'       : ('unknown field', 'scalar_tp', 0),
            'v'       : ('test field',    'scalar_tp', 'u'),
        }

        domain = FEDomain('domain', mesh)
        omega = domain.create_region('Omega', 'all')
        field = Field.from_args('scalar_tp', nm.float64, 1, omega,
                                approx_order=1)
        ff = {field.name : field}

        vv = Variables.from_conf(transform_variables(variables), ff)
        u = vv['u']
        u.set_from_mesh_vertices(data)

        integral = Integral('i', order=2)
        term = Term.new('ev_volume_integrate(u)', integral, omega, u=u)
        term.setup()
        val1 = term.evaluate(mode='qp')
        val1 = val1.ravel()

        qps = get_physical_qps(omega, integral)
        coors = qps.values

        val2 = u.evaluate_at(coors).ravel()

        self.report('max. difference:', nm.abs(val1 - val2).max())
        ok = nm.allclose(val1, val2, rtol=0.0, atol=1e-12)
        self.report('invariance in qp: %s' % ok)

        return ok
Beispiel #14
0
def prepare_variable(filename, n_components):
    from sfepy.discrete import FieldVariable
    from sfepy.discrete.fem import Mesh, FEDomain, Field

    mesh = Mesh.from_file(filename)

    bbox = mesh.get_bounding_box()
    dd = bbox[1, :] - bbox[0, :]
    data = nm.sin(4.0 * nm.pi * mesh.coors[:, 0:1] / dd[0]) * nm.cos(4.0 * nm.pi * mesh.coors[:, 1:2] / dd[1])

    domain = FEDomain("domain", mesh)
    omega = domain.create_region("Omega", "all")
    field = Field.from_args("field", nm.float64, n_components, omega, approx_order=2)

    u = FieldVariable("u", "parameter", field, primary_var_name="(set-to-None)")
    u.set_from_mesh_vertices(data * nm.arange(1, n_components + 1)[None, :])

    return u
Beispiel #15
0
    def test_projection_tri_quad(self):
        from sfepy.discrete.projections import make_l2_projection

        source = FieldVariable('us', 'unknown', self.field)

        coors = self.field.get_coor()
        vals = nm.sin(2.0 * nm.pi * coors[:,0] * coors[:,1])
        source.set_data(vals)

        name = op.join(self.options.out_dir,
                       'test_projection_tri_quad_source.vtk')
        source.save_as_mesh(name)

        mesh = Mesh.from_file('meshes/2d/square_quad.mesh',
                              prefix_dir=sfepy.data_dir)
        domain = FEDomain('domain', mesh)

        omega = domain.create_region('Omega', 'all')


        field = Field.from_args('bilinear', nm.float64, 'scalar', omega,
                                approx_order=1)

        target = FieldVariable('ut', 'unknown', field)

        make_l2_projection(target, source)

        name = op.join(self.options.out_dir,
                       'test_projection_tri_quad_target.vtk')
        target.save_as_mesh(name)

        bbox = self.field.domain.get_mesh_bounding_box()
        x = nm.linspace(bbox[0, 0] + 0.001, bbox[1, 0] - 0.001, 20)
        y = nm.linspace(bbox[0, 1] + 0.001, bbox[1, 1] - 0.001, 20)

        xx, yy = nm.meshgrid(x, y)
        test_coors = nm.c_[xx.ravel(), yy.ravel()].copy()

        vec1 = source.evaluate_at(test_coors)
        vec2 = target.evaluate_at(test_coors)

        ok = (nm.abs(vec1 - vec2) < 0.01).all()

        return ok
Beispiel #16
0
def prepare_variable(filename, n_components):
    from sfepy.discrete import FieldVariable
    from sfepy.discrete.fem import Mesh, FEDomain, Field

    mesh = Mesh.from_file(filename)

    bbox = mesh.get_bounding_box()
    dd = bbox[1,:] - bbox[0,:]
    data = (nm.sin(4.0 * nm.pi * mesh.coors[:,0:1] / dd[0])
            * nm.cos(4.0 * nm.pi * mesh.coors[:,1:2] / dd[1]))

    domain = FEDomain('domain', mesh)
    omega = domain.create_region('Omega', 'all')
    field = Field.from_args('field', nm.float64, n_components, omega,
                            approx_order=2)

    u = FieldVariable('u', 'parameter', field,
                      primary_var_name='(set-to-None)')
    u.set_from_mesh_vertices(nm.c_[tuple([data] * n_components)])

    return u
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 = FEDomain('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)
        v = FieldVariable('v', 'test', field, 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()
Beispiel #18
0
                            Equations, Problem)
from sfepy.discrete.fem import Mesh, FEDomain, Field
from sfepy.terms import Term
from sfepy.discrete.conditions import Conditions, EssentialBC
from sfepy.solvers.ls import ScipyDirect
from sfepy.solvers.nls import Newton
from sfepy.postprocess.viewer import Viewer
from sfepy.mechanics.matcoefs import stiffness_from_youngpoisson
from sfepy.mechanics.tensors import get_von_mises_stress

mesh = Mesh.from_file('meshes/voronoi_foam.vtk')
domain = FEDomain('domain', mesh)

min_z, max_z = domain.get_mesh_bounding_box()[:, 2]
eps = 5
omega = domain.create_region('Omega', 'all')
bot = domain.create_region('Bot', 'vertices in z < %.10f' % (min_z + eps),
                           'vertex')
top = domain.create_region('Top', 'vertices in z > %.10f' % (max_z - eps),
                           'vertex')

field = Field.from_args('fu', np.float64, 'vector', omega, approx_order=1)

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

# these are for stainless steel 316L
m = Material('m',
             D=stiffness_from_youngpoisson(dim=3, young=1.93e9, poisson=0.275),
             rho=8000.0)
Beispiel #19
0
def load_and_plot_fun(folder, filename, exact=None):
    """
    Parameters
    ----------
    folder : str
        folder where to look for files
    filename : str
        used in {name}.i.vtk, i = 0,1, ... tns - 1
        number of time steps
    exact : callable
        exact solution at the last frame
    """
    in_file = head(glob(pjoin(folder, "*.vtk")))

    coors, data = load_state_1D_vtk(in_file)

    approx_order = data.shape[0] - 1

    dmesh = Mesh.from_file(in_file)
    domain = FEDomain("", dmesh)
    omega = domain.create_region('Omega', 'all')

    field = DGField('f',
                    nm.float64,
                    'scalar',
                    omega,
                    approx_order=approx_order)
    # Sufficient quadrature order for the analytical expression.
    idiff = Integral('idiff', 20)

    u = FieldVariable("u", "unknown", field)

    eqs = Equations(
        [Equation('balance', SurfaceTerm("s()", "u", idiff, omega, u=u))])
    pb = Problem("err_est", equations=eqs)

    u.set_data(field.ravel_sol(data.swapaxes(0, 1)))

    num_qp = pb.evaluate('ev_volume_integrate.idiff.Omega(u)',
                         u=u,
                         integrals=Integrals([idiff]),
                         mode='qp')

    aux = Material('aux', function=sol_fun)
    ana_qp = pb.evaluate('ev_volume_integrate_mat.idiff.Omega(aux.u, u)',
                         aux=aux,
                         u=u,
                         integrals=Integrals([idiff]),
                         mode='qp')
    qps = pb.fields["f"].mapping.get_physical_qps(idiff.get_qp("1_2")[0])
    fqps = qps.flatten()

    plt.figure("Reconstructed solution")
    plt.gca().set_ylim(-.5, 3.)

    ww_approx, xx = reconstruct_legendre_dofs(coors, None, data)
    ww_exact = exact(xx)

    XN = xx[-1]
    X1 = xx[0]
    plt.plot([X1, XN], [2, 2], 'grey', alpha=.6)
    plt.plot([X1, XN], [0, 0], 'grey', alpha=.6)
    plt.plot(fqps, ana_qp.flatten(), label="$p_{exact}(1, x)$")
    plt.plot(fqps, num_qp.flatten(), label="$p_h(1, x)$")
    plt.legend()
    plt.show()
Beispiel #20
0
def create_local_problem(omega_gi, order):
    """
    Local problem definition using a domain corresponding to the global region
    `omega_gi`.
    """
    mesh = omega_gi.domain.mesh

    # All tasks have the whole mesh.
    bbox = mesh.get_bounding_box()
    min_x, max_x = bbox[:, 0]
    eps_x = 1e-8 * (max_x - min_x)

    mesh_i = Mesh.from_region(omega_gi, mesh, localize=True)
    domain_i = FEDomain('domain_i', mesh_i)
    omega_i = domain_i.create_region('Omega', 'all')

    gamma1_i = domain_i.create_region('Gamma1',
                                      'vertices in (x < %.10f)'
                                      % (min_x + eps_x),
                                      'facet', allow_empty=True)
    gamma2_i = domain_i.create_region('Gamma2',
                                      'vertices in (x > %.10f)'
                                      % (max_x - eps_x),
                                      'facet', allow_empty=True)

    field_i = Field.from_args('fu', nm.float64, 1, omega_i,
                              approx_order=order)

    output('number of local field DOFs:', field_i.n_nod)

    u_i = FieldVariable('u_i', 'unknown', field_i)
    v_i = FieldVariable('v_i', 'test', field_i, primary_var_name='u_i')

    integral = Integral('i', order=2*order)

    mat = Material('m', lam=10, mu=5)
    t1 = Term.new('dw_laplace(m.lam, v_i, u_i)',
                  integral, omega_i, m=mat, v_i=v_i, u_i=u_i)

    def _get_load(coors):
        val = nm.ones_like(coors[:, 0])
        for coor in coors.T:
            val *= nm.sin(4 * nm.pi * coor)
        return val

    def get_load(ts, coors, mode=None, **kwargs):
        if mode == 'qp':
            return {'val' : _get_load(coors).reshape(coors.shape[0], 1, 1)}

    load = Material('load', function=Function('get_load', get_load))

    t2 = Term.new('dw_volume_lvf(load.val, v_i)',
                  integral, omega_i, load=load, v_i=v_i)

    eq = Equation('balance', t1 - 100 * t2)
    eqs = Equations([eq])

    ebc1 = EssentialBC('ebc1', gamma1_i, {'u_i.all' : 0.0})
    ebc2 = EssentialBC('ebc2', gamma2_i, {'u_i.all' : 0.1})

    pb = Problem('problem_i', equations=eqs, active_only=False)
    pb.time_update(ebcs=Conditions([ebc1, ebc2]))
    pb.update_materials()

    return pb
def solve_problem(mesh_filename, options, comm):
    order_u = options.order_u
    order_p = options.order_p

    rank, size = comm.Get_rank(), comm.Get_size()

    output('rank', rank, 'of', size)

    mesh = Mesh.from_file(mesh_filename)

    if rank == 0:
        cell_tasks = pl.partition_mesh(mesh, size, use_metis=options.metis,
                                       verbose=True)

    else:
        cell_tasks = None

    domain = FEDomain('domain', mesh)
    omega = domain.create_region('Omega', 'all')
    field1 = Field.from_args('fu', nm.float64, mesh.dim, omega,
                             approx_order=order_u)
    field2 = Field.from_args('fp', nm.float64, 1, omega,
                             approx_order=order_p)
    fields = [field1, field2]

    output('distributing fields...')
    tt = time.clock()

    lfds, gfds = pl.distribute_fields_dofs(fields, cell_tasks,
                                           is_overlap=True,
                                           use_expand_dofs=True,
                                           comm=comm, verbose=True)

    output('...done in', time.clock() - tt)

    output('creating local problem...')
    tt = time.clock()

    cells = lfds[0].cells

    omega_gi = Region.from_cells(cells, domain)
    omega_gi.finalize()
    omega_gi.update_shape()

    pb = create_local_problem(omega_gi, [order_u, order_p])

    variables = pb.get_variables()

    state = State(variables)
    state.fill(0.0)
    state.apply_ebc()

    output('...done in', time.clock() - tt)


    output('allocating global system...')
    tt = time.clock()

    sizes, drange, pdofs = pl.setup_composite_dofs(lfds, fields, variables,
                                                   verbose=True)
    pmtx, psol, prhs = pl.create_petsc_system(pb.mtx_a, sizes, pdofs, drange,
                                              is_overlap=True, comm=comm,
                                              verbose=True)

    output('...done in', time.clock() - tt)

    output('creating solver...')
    tt = time.clock()

    conf = Struct(method='bcgsl', precond='jacobi', sub_precond=None,
                  i_max=10000, eps_a=1e-50, eps_r=1e-6, eps_d=1e4,
                  verbose=True)
    status = {}
    ls = PETScKrylovSolver(conf, comm=comm, mtx=pmtx, status=status)

    field_ranges = {}
    for ii, variable in enumerate(variables.iter_state(ordered=True)):
        field_ranges[variable.name] = lfds[ii].petsc_dofs_range

    ls.set_field_split(field_ranges, comm=comm)

    ev = PETScParallelEvaluator(pb, pdofs, drange, True,
                                psol, comm, verbose=True)

    nls_status = {}
    conf = Struct(method='newtonls',
                  i_max=5, eps_a=0, eps_r=1e-5, eps_s=0.0,
                  verbose=True)
    nls = PETScNonlinearSolver(conf, pmtx=pmtx, prhs=prhs, comm=comm,
                               fun=ev.eval_residual,
                               fun_grad=ev.eval_tangent_matrix,
                               lin_solver=ls, status=nls_status)

    output('...done in', time.clock() - tt)

    output('solving...')
    tt = time.clock()

    state = pb.create_state()
    state.apply_ebc()

    ev.psol_i[...] = state()
    ev.gather(psol, ev.psol_i)

    psol = nls(psol)

    ev.scatter(ev.psol_i, psol)
    sol0_i = ev.psol_i[...]

    output('...done in', time.clock() - tt)

    output('saving solution...')
    tt = time.clock()

    state.set_full(sol0_i)
    out = state.create_output_dict()

    filename = os.path.join(options.output_dir, 'sol_%02d.h5' % comm.rank)
    pb.domain.mesh.write(filename, io='auto', out=out)

    gather_to_zero = pl.create_gather_to_zero(psol)

    psol_full = gather_to_zero(psol)

    if comm.rank == 0:
        sol = psol_full[...].copy()

        u = FieldVariable('u', 'parameter', field1,
                          primary_var_name='(set-to-None)')
        remap = gfds[0].id_map
        ug = sol[remap]

        p = FieldVariable('p', 'parameter', field2,
                          primary_var_name='(set-to-None)')
        remap = gfds[1].id_map
        pg = sol[remap]

        if (((order_u == 1) and (order_p == 1))
            or (options.linearization == 'strip')):
            out = u.create_output(ug)
            out.update(p.create_output(pg))
            filename = os.path.join(options.output_dir, 'sol.h5')
            mesh.write(filename, io='auto', out=out)

        else:
            out = u.create_output(ug, linearization=Struct(kind='adaptive',
                                                           min_level=0,
                                                           max_level=order_u,
                                                           eps=1e-3))

            filename = os.path.join(options.output_dir, 'sol_u.h5')
            out['u'].mesh.write(filename, io='auto', out=out)

            out = p.create_output(pg, linearization=Struct(kind='adaptive',
                                                           min_level=0,
                                                           max_level=order_p,
                                                           eps=1e-3))

            filename = os.path.join(options.output_dir, 'sol_p.h5')
            out['p'].mesh.write(filename, io='auto', out=out)

    output('...done in', time.clock() - tt)
Beispiel #22
0
def main():
    from sfepy import data_dir

    parser = OptionParser(usage=usage, version='%prog')
    parser.add_option('--young', metavar='float', type=float,
                      action='store', dest='young',
                      default=2000.0, help=helps['young'])
    parser.add_option('--poisson', metavar='float', type=float,
                      action='store', dest='poisson',
                      default=0.4, help=helps['poisson'])
    parser.add_option('--load', metavar='float', type=float,
                      action='store', dest='load',
                      default=-1000.0, help=helps['load'])
    parser.add_option('--order', metavar='int', type=int,
                      action='store', dest='order',
                      default=1, help=helps['order'])
    parser.add_option('-r', '--refine', metavar='int', type=int,
                      action='store', dest='refine',
                      default=0, help=helps['refine'])
    parser.add_option('-s', '--show',
                      action="store_true", dest='show',
                      default=False, help=helps['show'])
    parser.add_option('-p', '--probe',
                      action="store_true", dest='probe',
                      default=False, help=helps['probe'])
    options, args = parser.parse_args()

    assert_((0.0 < options.poisson < 0.5),
            "Poisson's ratio must be in ]0, 0.5[!")
    assert_((0 < options.order),
            'displacement approximation order must be at least 1!')

    output('using values:')
    output("  Young's modulus:", options.young)
    output("  Poisson's ratio:", options.poisson)
    output('  vertical load:', options.load)
    output('uniform mesh refinement level:', options.refine)

    # Build the problem definition.
    mesh = Mesh.from_file(data_dir + '/meshes/2d/its2D.mesh')
    domain = FEDomain('domain', mesh)

    if options.refine > 0:
        for ii in range(options.refine):
            output('refine %d...' % ii)
            domain = domain.refine()
            output('... %d nodes %d elements'
                   % (domain.shape.n_nod, domain.shape.n_el))

    omega = domain.create_region('Omega', 'all')
    left = domain.create_region('Left',
                                'vertices in x < 0.001', 'facet')
    bottom = domain.create_region('Bottom',
                                  'vertices in y < 0.001', 'facet')
    top = domain.create_region('Top', 'vertex 2', 'vertex')

    field = Field.from_args('fu', nm.float64, 'vector', omega,
                            approx_order=options.order)

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

    D = stiffness_from_youngpoisson(2, options.young, options.poisson)

    asphalt = Material('Asphalt', D=D)
    load = Material('Load', values={'.val' : [0.0, options.load]})

    integral = Integral('i', order=2*options.order)
    integral0 = Integral('i', order=0)

    t1 = Term.new('dw_lin_elastic(Asphalt.D, v, u)',
                  integral, omega, Asphalt=asphalt, v=v, u=u)
    t2 = Term.new('dw_point_load(Load.val, v)',
                  integral0, top, Load=load, v=v)
    eq = Equation('balance', t1 - t2)
    eqs = Equations([eq])

    xsym = EssentialBC('XSym', bottom, {'u.1' : 0.0})
    ysym = EssentialBC('YSym', left, {'u.0' : 0.0})

    ls = ScipyDirect({})

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

    pb = Problem('elasticity', equations=eqs, nls=nls, ls=ls)

    pb.time_update(ebcs=Conditions([xsym, ysym]))

    # Solve the problem.
    state = pb.solve()
    output(nls_status)

    # Postprocess the solution.
    out = state.create_output_dict()
    out = stress_strain(out, pb, state, extend=True)
    pb.save_state('its2D_interactive.vtk', out=out)

    gdata = geometry_data['2_3']
    nc = len(gdata.coors)

    integral_vn = Integral('ivn', coors=gdata.coors,
                          weights=[gdata.volume / nc] * nc)

    nodal_stress(out, pb, state, integrals=Integrals([integral_vn]))

    if options.probe:
        # Probe the solution.
        probes, labels = gen_lines(pb)

        sfield = Field.from_args('sym_tensor', nm.float64, 3, omega,
                                approx_order=options.order - 1)
        stress = FieldVariable('stress', 'parameter', sfield,
                               primary_var_name='(set-to-None)')
        strain = FieldVariable('strain', 'parameter', sfield,
                               primary_var_name='(set-to-None)')

        cfield = Field.from_args('component', nm.float64, 1, omega,
                                 approx_order=options.order - 1)
        component = FieldVariable('component', 'parameter', cfield,
                                  primary_var_name='(set-to-None)')

        ev = pb.evaluate
        order = 2 * (options.order - 1)
        strain_qp = ev('ev_cauchy_strain.%d.Omega(u)' % order, mode='qp')
        stress_qp = ev('ev_cauchy_stress.%d.Omega(Asphalt.D, u)' % order,
                       mode='qp', copy_materials=False)

        project_by_component(strain, strain_qp, component, order)
        project_by_component(stress, stress_qp, component, order)

        all_results = []
        for ii, probe in enumerate(probes):
            fig, results = probe_results(u, strain, stress, probe, labels[ii])

            fig.savefig('its2D_interactive_probe_%d.png' % ii)
            all_results.append(results)

        for ii, results in enumerate(all_results):
            output('probe %d:' % ii)
            output.level += 2
            for key, res in ordered_iteritems(results):
                output(key + ':')
                val = res[1]
                output('  min: %+.2e, mean: %+.2e, max: %+.2e'
                       % (val.min(), val.mean(), val.max()))
            output.level -= 2

    if options.show:
        # Show the solution. If the approximation order is greater than 1, the
        # extra DOFs are simply thrown away.
        from sfepy.postprocess.viewer import Viewer

        view = Viewer('its2D_interactive.vtk')
        view(vector_mode='warp_norm', rel_scaling=1,
             is_scalar_bar=True, is_wireframe=True)
Beispiel #23
0
def main():
    from sfepy import data_dir

    parser = OptionParser(usage=usage, version='%prog')
    parser.add_option('--diffusivity', metavar='float', type=float,
                      action='store', dest='diffusivity',
                      default=1e-5, help=helps['diffusivity'])
    parser.add_option('--ic-max', metavar='float', type=float,
                      action='store', dest='ic_max',
                      default=2.0, help=helps['ic_max'])
    parser.add_option('--order', metavar='int', type=int,
                      action='store', dest='order',
                      default=2, help=helps['order'])
    parser.add_option('-r', '--refine', metavar='int', type=int,
                      action='store', dest='refine',
                      default=0, help=helps['refine'])
    parser.add_option('-p', '--probe',
                      action="store_true", dest='probe',
                      default=False, help=helps['probe'])
    parser.add_option('-s', '--show',
                      action="store_true", dest='show',
                      default=False, help=helps['show'])
    options, args = parser.parse_args()

    assert_((0 < options.order),
            'temperature approximation order must be at least 1!')

    output('using values:')
    output('  diffusivity:', options.diffusivity)
    output('  max. IC value:', options.ic_max)
    output('uniform mesh refinement level:', options.refine)

    mesh = Mesh.from_file(data_dir + '/meshes/3d/cylinder.mesh')
    domain = FEDomain('domain', mesh)

    if options.refine > 0:
        for ii in range(options.refine):
            output('refine %d...' % ii)
            domain = domain.refine()
            output('... %d nodes %d elements'
                   % (domain.shape.n_nod, domain.shape.n_el))

    omega = domain.create_region('Omega', 'all')
    left = domain.create_region('Left',
                                'vertices in x < 0.00001', 'facet')
    right = domain.create_region('Right',
                                 'vertices in x > 0.099999', 'facet')

    field = Field.from_args('fu', nm.float64, 'scalar', omega,
                            approx_order=options.order)

    T = FieldVariable('T', 'unknown', field, history=1)
    s = FieldVariable('s', 'test', field, primary_var_name='T')

    m = Material('m', diffusivity=options.diffusivity * nm.eye(3))

    integral = Integral('i', order=2*options.order)

    t1 = Term.new('dw_diffusion(m.diffusivity, s, T)',
                  integral, omega, m=m, s=s, T=T)
    t2 = Term.new('dw_volume_dot(s, dT/dt)',
                  integral, omega, s=s, T=T)
    eq = Equation('balance', t1 + t2)
    eqs = Equations([eq])

    # Boundary conditions.
    ebc1 = EssentialBC('T1', left, {'T.0' : 2.0})
    ebc2 = EssentialBC('T2', right, {'T.0' : -2.0})

    # Initial conditions.
    def get_ic(coors, ic):
        x, y, z = coors.T
        return 2 - 40.0 * x + options.ic_max * nm.sin(4 * nm.pi * x / 0.1)
    ic_fun = Function('ic_fun', get_ic)
    ic = InitialCondition('ic', omega, {'T.0' : ic_fun})

    ls = ScipyDirect({})

    nls_status = IndexedStruct()
    nls = Newton({'is_linear' : True}, lin_solver=ls, status=nls_status)

    pb = Problem('heat', equations=eqs, nls=nls, ls=ls)
    pb.set_bcs(ebcs=Conditions([ebc1, ebc2]))
    pb.set_ics(Conditions([ic]))

    tss = SimpleTimeSteppingSolver({'t0' : 0.0, 't1' : 100.0, 'n_step' : 11},
                                   problem=pb)
    tss.init_time()

    if options.probe:
        # Prepare probe data.
        probes, labels = gen_lines(pb)

        ev = pb.evaluate
        order = 2 * (options.order - 1)

        gfield = Field.from_args('gu', nm.float64, 'vector', omega,
                                approx_order=options.order - 1)
        dvel = FieldVariable('dvel', 'parameter', gfield,
                             primary_var_name='(set-to-None)')
        cfield = Field.from_args('gu', nm.float64, 'scalar', omega,
                                approx_order=options.order - 1)
        component = FieldVariable('component', 'parameter', cfield,
                                  primary_var_name='(set-to-None)')

        nls_options = {'eps_a' : 1e-16, 'i_max' : 1}

        if options.show:
            plt.ion()

    # Solve the problem using the time stepping solver.
    suffix = tss.ts.suffix
    for step, time, state in tss():
        if options.probe:
            # Probe the solution.
            dvel_qp = ev('ev_diffusion_velocity.%d.Omega(m.diffusivity, T)'
                         % order, copy_materials=False, mode='qp')
            project_by_component(dvel, dvel_qp, component, order,
                                 nls_options=nls_options)

            all_results = []
            for ii, probe in enumerate(probes):
                fig, results = probe_results(ii, T, dvel, probe, labels[ii])

                all_results.append(results)

            plt.tight_layout()
            fig.savefig('time_poisson_interactive_probe_%s.png'
                        % (suffix % step), bbox_inches='tight')

            if options.show:
                plt.draw()

            for ii, results in enumerate(all_results):
                output('probe %d (%s):' % (ii, probes[ii].name))
                output.level += 2
                for key, res in ordered_iteritems(results):
                    output(key + ':')
                    val = res[1]
                    output('  min: %+.2e, mean: %+.2e, max: %+.2e'
                           % (val.min(), val.mean(), val.max()))
                output.level -= 2
def solve_problem(mesh_filename, options, comm):
    order = options.order

    rank, size = comm.Get_rank(), comm.Get_size()

    output('rank', rank, 'of', size)

    mesh = Mesh.from_file(mesh_filename)

    if rank == 0:
        cell_tasks = pl.partition_mesh(mesh,
                                       size,
                                       use_metis=options.metis,
                                       verbose=True)

    else:
        cell_tasks = None

    domain = FEDomain('domain', mesh)
    omega = domain.create_region('Omega', 'all')
    field = Field.from_args('fu', nm.float64, 1, omega, approx_order=order)

    output('distributing field %s...' % field.name)
    tt = time.clock()

    lfds, gfds = pl.distribute_fields_dofs([field],
                                           cell_tasks,
                                           is_overlap=True,
                                           comm=comm,
                                           verbose=True)
    lfd = lfds[0]

    output('...done in', time.clock() - tt)

    if rank == 0:
        dof_maps = gfds[0].dof_maps
        id_map = gfds[0].id_map

        if options.verify:
            verify_save_dof_maps(field,
                                 cell_tasks,
                                 dof_maps,
                                 id_map,
                                 options,
                                 verbose=True)

        if options.plot:
            ppd.plot_partitioning([None, None], field, cell_tasks, gfds[0],
                                  options.output_dir, size)

    output('creating local problem...')
    tt = time.clock()

    omega_gi = Region.from_cells(lfd.cells, field.domain)
    omega_gi.finalize()
    omega_gi.update_shape()

    pb = create_local_problem(omega_gi, order)

    output('...done in', time.clock() - tt)

    variables = pb.get_variables()
    eqs = pb.equations

    u_i = variables['u_i']
    field_i = u_i.field

    if options.plot:
        ppd.plot_local_dofs([None, None], field, field_i, omega_gi,
                            options.output_dir, rank)

    output('allocating global system...')
    tt = time.clock()

    sizes, drange = pl.get_sizes(lfd.petsc_dofs_range, field.n_nod, 1)
    output('sizes:', sizes)
    output('drange:', drange)

    pdofs = pl.get_local_ordering(field_i, lfd.petsc_dofs_conn)

    output('pdofs:', pdofs)

    pmtx, psol, prhs = pl.create_petsc_system(pb.mtx_a,
                                              sizes,
                                              pdofs,
                                              drange,
                                              is_overlap=True,
                                              comm=comm,
                                              verbose=True)

    output('...done in', time.clock() - tt)

    output('evaluating local problem...')
    tt = time.clock()

    state = State(variables)
    state.fill(0.0)
    state.apply_ebc()

    rhs_i = eqs.eval_residuals(state())
    # This must be after pl.create_petsc_system() call!
    mtx_i = eqs.eval_tangent_matrices(state(), pb.mtx_a)

    output('...done in', time.clock() - tt)

    output('assembling global system...')
    tt = time.clock()

    pl.apply_ebc_to_matrix(mtx_i, u_i.eq_map.eq_ebc)
    pl.assemble_rhs_to_petsc(prhs,
                             rhs_i,
                             pdofs,
                             drange,
                             is_overlap=True,
                             comm=comm,
                             verbose=True)
    pl.assemble_mtx_to_petsc(pmtx,
                             mtx_i,
                             pdofs,
                             drange,
                             is_overlap=True,
                             comm=comm,
                             verbose=True)

    output('...done in', time.clock() - tt)

    output('creating solver...')
    tt = time.clock()

    conf = Struct(method='cg',
                  precond='gamg',
                  sub_precond=None,
                  i_max=10000,
                  eps_a=1e-50,
                  eps_r=1e-5,
                  eps_d=1e4,
                  verbose=True)
    status = {}
    ls = PETScKrylovSolver(conf, comm=comm, mtx=pmtx, status=status)

    output('...done in', time.clock() - tt)

    output('solving...')
    tt = time.clock()

    psol = ls(prhs, psol, conf)

    psol_i = pl.create_local_petsc_vector(pdofs)
    gather, scatter = pl.create_gather_scatter(pdofs, psol_i, psol, comm=comm)

    scatter(psol_i, psol)

    sol0_i = state() - psol_i[...]
    psol_i[...] = sol0_i

    gather(psol, psol_i)

    output('...done in', time.clock() - tt)

    output('saving solution...')
    tt = time.clock()

    u_i.set_data(sol0_i)
    out = u_i.create_output()

    filename = os.path.join(options.output_dir, 'sol_%02d.h5' % comm.rank)
    pb.domain.mesh.write(filename, io='auto', out=out)

    gather_to_zero = pl.create_gather_to_zero(psol)

    psol_full = gather_to_zero(psol)

    if comm.rank == 0:
        sol = psol_full[...].copy()[id_map]

        u = FieldVariable('u',
                          'parameter',
                          field,
                          primary_var_name='(set-to-None)')

        filename = os.path.join(options.output_dir, 'sol.h5')
        if (order == 1) or (options.linearization == 'strip'):
            out = u.create_output(sol)
            mesh.write(filename, io='auto', out=out)

        else:
            out = u.create_output(sol,
                                  linearization=Struct(kind='adaptive',
                                                       min_level=0,
                                                       max_level=order,
                                                       eps=1e-3))

            out['u'].mesh.write(filename, io='auto', out=out)

    output('...done in', time.clock() - tt)

    if options.show:
        plt.show()
Beispiel #25
0
    def from_conf(conf, options):
        from sfepy.discrete import FieldVariable, Variables, Problem
        from sfepy.discrete.fem import Mesh, FEDomain, Field

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

        omega = domain.create_region('Omega', 'all')
        domain.create_region('Left', 'vertices in (x < -0.499)', 'facet')
        domain.create_region(
            'LeftStrip', 'vertices in (x < -0.499)'
            ' & (y > -0.199) & (y < 0.199)', 'facet')
        domain.create_region('LeftFix', 'r.Left -v r.LeftStrip', 'facet')
        domain.create_region('Right', 'vertices in (x > 0.499)', 'facet')
        domain.create_region(
            'RightStrip', 'vertices in (x > 0.499)'
            ' & (y > -0.199) & (y < 0.199)', 'facet')
        domain.create_region('RightFix', 'r.Right -v r.RightStrip', 'facet')

        fu = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=2)
        u = FieldVariable('u', 'unknown', fu)

        fp = Field.from_args('fp', nm.float64, 'scalar', omega, approx_order=2)
        p = FieldVariable('p', 'unknown', fp)

        pb = Problem('test', domain=domain, fields=[fu, fp], auto_conf=False)

        test = Test(problem=pb,
                    variables=Variables([u, p]),
                    conf=conf,
                    options=options)
        return test
Beispiel #26
0
def main():
    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('-s',
                        '--scale',
                        metavar='scale',
                        action='store',
                        dest='scale',
                        default=None,
                        help=helps['scale'])
    parser.add_argument('-c',
                        '--center',
                        metavar='center',
                        action='store',
                        dest='center',
                        default=None,
                        help=helps['center'])
    parser.add_argument('-r',
                        '--refine',
                        metavar='level',
                        action='store',
                        type=int,
                        dest='refine',
                        default=0,
                        help=helps['refine'])
    parser.add_argument('-f',
                        '--format',
                        metavar='format',
                        action='store',
                        type=str,
                        dest='format',
                        default=None,
                        help=helps['format'])
    parser.add_argument('-l',
                        '--list',
                        action='store_true',
                        dest='list',
                        help=helps['list'])
    parser.add_argument('-m',
                        '--merge',
                        action='store_true',
                        dest='merge',
                        help=helps['merge'])
    parser.add_argument('-t',
                        '--tri-tetra',
                        action='store_true',
                        dest='tri_tetra',
                        help=helps['tri-tetra'])
    parser.add_argument('-2',
                        '--2d',
                        action='store_true',
                        dest='force_2d',
                        help=helps['2d'])
    parser.add_argument('--save-per-mat',
                        action='store_true',
                        dest='save_per_mat',
                        help=helps['save-per-mat'])
    parser.add_argument('--remesh',
                        metavar='options',
                        action='store',
                        dest='remesh',
                        default=None,
                        help=helps['remesh'])
    parser.add_argument('filename_in')
    parser.add_argument('filename_out')
    options = parser.parse_args()

    if options.list:
        output('Supported readable mesh formats:')
        output('--------------------------------')
        output_mesh_formats('r')
        output('')
        output('Supported writable mesh formats:')
        output('--------------------------------')
        output_mesh_formats('w')
        sys.exit(0)

    scale = _parse_val_or_vec(options.scale, 'scale', parser)
    center = _parse_val_or_vec(options.center, 'center', parser)

    filename_in = options.filename_in
    filename_out = options.filename_out

    if options.remesh:
        import tempfile
        import shlex
        import subprocess

        dirname = tempfile.mkdtemp()

        is_surface = options.remesh.startswith('q')
        if is_surface:
            mesh = Mesh.from_file(filename_in)
            domain = FEDomain(mesh.name, mesh)
            region = domain.create_region('surf', 'vertices of surface',
                                          'facet')
            surf_mesh = Mesh.from_region(region,
                                         mesh,
                                         localize=True,
                                         is_surface=True)

            filename = op.join(dirname, 'surf.mesh')
            surf_mesh.write(filename, io='auto')

        else:
            import shutil

            shutil.copy(filename_in, dirname)
            filename = op.join(dirname, op.basename(filename_in))

        qopts = ''.join(options.remesh.split())  # Remove spaces.
        command = 'tetgen -BFENkACp%s %s' % (qopts, filename)
        args = shlex.split(command)
        subprocess.call(args)

        root, ext = op.splitext(filename)
        mesh = Mesh.from_file(root + '.1.vtk')

        remove_files(dirname)

    else:
        mesh = Mesh.from_file(filename_in)

    if options.force_2d:
        data = list(mesh._get_io_data())
        data[0] = data[0][:, :2]
        mesh = Mesh.from_data(mesh.name, *data)

    if scale is not None:
        if len(scale) == 1:
            tr = nm.eye(mesh.dim, dtype=nm.float64) * scale
        elif len(scale) == mesh.dim:
            tr = nm.diag(scale)
        else:
            raise ValueError('bad scale! (%s)' % scale)
        mesh.transform_coors(tr)

    if center is not None:
        cc = 0.5 * mesh.get_bounding_box().sum(0)
        shift = center - cc
        tr = nm.c_[nm.eye(mesh.dim, dtype=nm.float64), shift[:, None]]
        mesh.transform_coors(tr)

    if options.refine > 0:
        domain = FEDomain(mesh.name, mesh)
        output('initial mesh: %d nodes %d elements' %
               (domain.shape.n_nod, domain.shape.n_el))

        for ii in range(options.refine):
            output('refine %d...' % ii)
            domain = domain.refine()
            output('... %d nodes %d elements' %
                   (domain.shape.n_nod, domain.shape.n_el))

        mesh = domain.mesh

    if options.tri_tetra > 0:
        conns = None
        for k, new_desc in [('3_8', '3_4'), ('2_4', '2_3')]:
            if k in mesh.descs:
                conns = mesh.get_conn(k)
                break

        if conns is not None:
            nelo = conns.shape[0]
            output('initial mesh: %d elements' % nelo)

            new_conns = elems_q2t(conns)
            nn = new_conns.shape[0] // nelo
            new_cgroups = nm.repeat(mesh.cmesh.cell_groups, nn)

            output('new mesh: %d elements' % new_conns.shape[0])
            mesh = Mesh.from_data(mesh.name, mesh.coors,
                                  mesh.cmesh.vertex_groups, [new_conns],
                                  [new_cgroups], [new_desc])

    if options.merge:
        desc = mesh.descs[0]
        coor, ngroups, conns = fix_double_nodes(mesh.coors,
                                                mesh.cmesh.vertex_groups,
                                                mesh.get_conn(desc), 1e-9)
        mesh = Mesh.from_data(mesh.name + '_merged', coor, ngroups, [conns],
                              [mesh.cmesh.cell_groups], [desc])

    if options.save_per_mat:
        desc = mesh.descs[0]
        conns, cgroups = mesh.get_conn(desc), mesh.cmesh.cell_groups
        coors, ngroups = mesh.coors, mesh.cmesh.vertex_groups
        mat_ids = nm.unique(cgroups)

        for mat_id in mat_ids:
            idxs = nm.where(cgroups == mat_id)[0]
            imesh = Mesh.from_data(mesh.name + '_matid_%d' % mat_id, coors,
                                   ngroups, [conns[idxs]], [cgroups[idxs]],
                                   [desc])

            fbase, fext = op.splitext(filename_out)
            ifilename_out = '%s_matid_%d%s' % (fbase, mat_id, fext)
            io = MeshIO.for_format(ifilename_out,
                                   format=options.format,
                                   writable=True)
            output('writing %s...' % ifilename_out)
            imesh.write(ifilename_out, io=io)
            output('...done')

    io = MeshIO.for_format(filename_out, format=options.format, writable=True)

    cell_types = ', '.join(supported_cell_types[io.format])
    output('writing [%s] %s...' % (cell_types, filename_out))
    mesh.write(filename_out, io=io)
    output('...done')
Beispiel #27
0
def main():
    from sfepy import data_dir

    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('--version', action='version', version='%(prog)s')
    parser.add_argument('--diffusivity',
                        metavar='float',
                        type=float,
                        action='store',
                        dest='diffusivity',
                        default=1e-5,
                        help=helps['diffusivity'])
    parser.add_argument('--ic-max',
                        metavar='float',
                        type=float,
                        action='store',
                        dest='ic_max',
                        default=2.0,
                        help=helps['ic_max'])
    parser.add_argument('--order',
                        metavar='int',
                        type=int,
                        action='store',
                        dest='order',
                        default=2,
                        help=helps['order'])
    parser.add_argument('-r',
                        '--refine',
                        metavar='int',
                        type=int,
                        action='store',
                        dest='refine',
                        default=0,
                        help=helps['refine'])
    parser.add_argument('-p',
                        '--probe',
                        action="store_true",
                        dest='probe',
                        default=False,
                        help=helps['probe'])
    parser.add_argument('-s',
                        '--show',
                        action="store_true",
                        dest='show',
                        default=False,
                        help=helps['show'])
    options = parser.parse_args()

    assert_((0 < options.order),
            'temperature approximation order must be at least 1!')

    output('using values:')
    output('  diffusivity:', options.diffusivity)
    output('  max. IC value:', options.ic_max)
    output('uniform mesh refinement level:', options.refine)

    mesh = Mesh.from_file(data_dir + '/meshes/3d/cylinder.mesh')
    domain = FEDomain('domain', mesh)

    if options.refine > 0:
        for ii in range(options.refine):
            output('refine %d...' % ii)
            domain = domain.refine()
            output('... %d nodes %d elements' %
                   (domain.shape.n_nod, domain.shape.n_el))

    omega = domain.create_region('Omega', 'all')
    left = domain.create_region('Left', 'vertices in x < 0.00001', 'facet')
    right = domain.create_region('Right', 'vertices in x > 0.099999', 'facet')

    field = Field.from_args('fu',
                            nm.float64,
                            'scalar',
                            omega,
                            approx_order=options.order)

    T = FieldVariable('T', 'unknown', field, history=1)
    s = FieldVariable('s', 'test', field, primary_var_name='T')

    m = Material('m', diffusivity=options.diffusivity * nm.eye(3))

    integral = Integral('i', order=2 * options.order)

    t1 = Term.new('dw_diffusion(m.diffusivity, s, T)',
                  integral,
                  omega,
                  m=m,
                  s=s,
                  T=T)
    t2 = Term.new('dw_volume_dot(s, dT/dt)', integral, omega, s=s, T=T)
    eq = Equation('balance', t1 + t2)
    eqs = Equations([eq])

    # Boundary conditions.
    ebc1 = EssentialBC('T1', left, {'T.0': 2.0})
    ebc2 = EssentialBC('T2', right, {'T.0': -2.0})

    # Initial conditions.
    def get_ic(coors, ic):
        x, y, z = coors.T
        return 2 - 40.0 * x + options.ic_max * nm.sin(4 * nm.pi * x / 0.1)

    ic_fun = Function('ic_fun', get_ic)
    ic = InitialCondition('ic', omega, {'T.0': ic_fun})

    pb = Problem('heat', equations=eqs)
    pb.set_bcs(ebcs=Conditions([ebc1, ebc2]))
    pb.set_ics(Conditions([ic]))

    state0 = pb.get_initial_state()
    init_fun, prestep_fun, _poststep_fun = pb.get_tss_functions(state0)

    ls = ScipyDirect({})
    nls_status = IndexedStruct()
    nls = Newton({'is_linear': True}, lin_solver=ls, status=nls_status)
    tss = SimpleTimeSteppingSolver({
        't0': 0.0,
        't1': 100.0,
        'n_step': 11
    },
                                   nls=nls,
                                   context=pb,
                                   verbose=True)
    pb.set_solver(tss)

    if options.probe:
        # Prepare probe data.
        probes, labels = gen_probes(pb)

        ev = pb.evaluate
        order = 2 * (options.order - 1)

        gfield = Field.from_args('gu',
                                 nm.float64,
                                 'vector',
                                 omega,
                                 approx_order=options.order - 1)
        dvel = FieldVariable('dvel',
                             'parameter',
                             gfield,
                             primary_var_name='(set-to-None)')
        cfield = Field.from_args('gu',
                                 nm.float64,
                                 'scalar',
                                 omega,
                                 approx_order=options.order - 1)
        component = FieldVariable('component',
                                  'parameter',
                                  cfield,
                                  primary_var_name='(set-to-None)')

        nls_options = {'eps_a': 1e-16, 'i_max': 1}

        suffix = tss.ts.suffix

        def poststep_fun(ts, vec):
            _poststep_fun(ts, vec)

            # Probe the solution.
            dvel_qp = ev('ev_diffusion_velocity.%d.Omega(m.diffusivity, T)' %
                         order,
                         copy_materials=False,
                         mode='qp')
            project_by_component(dvel,
                                 dvel_qp,
                                 component,
                                 order,
                                 nls_options=nls_options)

            all_results = []
            for ii, probe in enumerate(probes):
                fig, results = probe_results(ii, T, dvel, probe, labels[ii])

                all_results.append(results)

            plt.tight_layout()
            fig.savefig('time_poisson_interactive_probe_%s.png' %
                        (suffix % ts.step),
                        bbox_inches='tight')

            for ii, results in enumerate(all_results):
                output('probe %d (%s):' % (ii, probes[ii].name))
                output.level += 2
                for key, res in ordered_iteritems(results):
                    output(key + ':')
                    val = res[1]
                    output('  min: %+.2e, mean: %+.2e, max: %+.2e' %
                           (val.min(), val.mean(), val.max()))
                output.level -= 2

    else:
        poststep_fun = _poststep_fun

    pb.time_update(tss.ts)
    state0.apply_ebc()

    # This is required if {'is_linear' : True} is passed to Newton.
    mtx = prepare_matrix(pb, state0)
    pb.try_presolve(mtx)

    tss_status = IndexedStruct()
    tss(state0.get_vec(pb.active_only),
        init_fun=init_fun,
        prestep_fun=prestep_fun,
        poststep_fun=poststep_fun,
        status=tss_status)

    output(tss_status)

    if options.show:
        plt.show()
Beispiel #28
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 = FEDomain('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)
        v = FieldVariable('v', 'test', field, primary_var_name='u')

        m = Material('m', D=stiffness_from_lame(dim, 1.0, 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(m.D, 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()
Beispiel #29
0
    def test_projection_iga_fem(self):
        from sfepy.discrete import FieldVariable
        from sfepy.discrete.fem import FEDomain, Field
        from sfepy.discrete.iga.domain import IGDomain
        from sfepy.mesh.mesh_generators import gen_block_mesh
        from sfepy.discrete.iga.domain_generators import gen_patch_block_domain
        from sfepy.discrete.projections import (make_l2_projection,
                                                make_l2_projection_data)

        shape = [10, 12, 12]
        dims = [5, 6, 6]
        centre = [0, 0, 0]
        degrees = [2, 2, 2]

        nurbs, bmesh, regions = gen_patch_block_domain(dims,
                                                       shape,
                                                       centre,
                                                       degrees,
                                                       cp_mode='greville',
                                                       name='iga')
        ig_domain = IGDomain('iga', nurbs, bmesh, regions=regions)

        ig_omega = ig_domain.create_region('Omega', 'all')
        ig_field = Field.from_args('iga',
                                   nm.float64,
                                   1,
                                   ig_omega,
                                   approx_order='iga',
                                   poly_space_base='iga')
        ig_u = FieldVariable('ig_u',
                             'parameter',
                             ig_field,
                             primary_var_name='(set-to-None)')

        mesh = gen_block_mesh(dims, shape, centre, name='fem')
        fe_domain = FEDomain('fem', mesh)

        fe_omega = fe_domain.create_region('Omega', 'all')
        fe_field = Field.from_args('fem',
                                   nm.float64,
                                   1,
                                   fe_omega,
                                   approx_order=2)
        fe_u = FieldVariable('fe_u',
                             'parameter',
                             fe_field,
                             primary_var_name='(set-to-None)')

        def _eval_data(ts, coors, mode, **kwargs):
            return nm.prod(coors**2, axis=1)[:, None, None]

        make_l2_projection_data(ig_u, _eval_data)

        make_l2_projection(fe_u, ig_u)  # This calls ig_u.evaluate_at().

        coors = 0.5 * nm.random.rand(20, 3) * dims

        ig_vals = ig_u.evaluate_at(coors)
        fe_vals = fe_u.evaluate_at(coors)

        ok = nm.allclose(ig_vals, fe_vals, rtol=0.0, atol=1e-12)
        if not ok:
            self.report('iga-fem projection failed!')
            self.report('coors:')
            self.report(coors)
            self.report('iga fem diff:')
            self.report(nm.c_[ig_vals, fe_vals, nm.abs(ig_vals - fe_vals)])

        return ok
Beispiel #30
0
def main(argv):
    if argv is None:
        argv = sys.argv[1:]
    args = parser.parse_args(argv)

    # vvvvvvvvvvvvvvvv #
    approx_order = 2
    # ^^^^^^^^^^^^^^^^ #

    # Setup output names
    outputs_folder = "../outputs"

    domain_name = "domain_1D"
    problem_name = "iburgers_1D"
    output_folder = pjoin(outputs_folder, problem_name, str(approx_order))
    output_format = "vtk"
    save_timestn = 100
    clear_folder(pjoin(output_folder, "*." + output_format))
    configure_output({
        'output_screen':
        True,
        'output_log_name':
        pjoin(output_folder, f"last_run_{problem_name}_{approx_order}.txt")
    })

    # ------------
    # | Get mesh |
    # ------------
    X1 = 0.
    XN = 1.
    n_nod = 100
    n_el = n_nod - 1
    mesh = get_gen_1D_mesh_hook(X1, XN, n_nod).read(None)

    # -----------------------------
    # | Create problem components |
    # -----------------------------

    integral = Integral('i', order=approx_order * 2)
    domain = FEDomain(domain_name, mesh)
    omega = domain.create_region('Omega', 'all')
    left = domain.create_region('Gamma1', 'vertices in x == %.10f' % X1,
                                'vertex')
    right = domain.create_region('Gamma2', 'vertices in x == %.10f' % XN,
                                 'vertex')
    field = DGField('dgfu',
                    nm.float64,
                    'scalar',
                    omega,
                    approx_order=approx_order)

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

    MassT = DotProductVolumeTerm("adv_vol(v, u)",
                                 "v, u",
                                 integral,
                                 omega,
                                 u=u,
                                 v=v)

    velo = nm.array(1.0)

    def adv_fun(u):
        vu = velo.T * u[..., None]
        return vu

    def adv_fun_d(u):
        v1 = velo.T * nm.ones(u.shape + (1, ))
        return v1

    burg_velo = velo.T / nm.linalg.norm(velo)

    def burg_fun(u):
        vu = burg_velo * u[..., None]**2
        return vu

    def burg_fun_d(u):
        v1 = 2 * burg_velo * u[..., None]
        return v1

    StiffT = NonlinearScalarDotGradTerm("burgers_stiff(f, df, u, v)",
                                        "fun , fun_d, u[-1], v",
                                        integral,
                                        omega,
                                        u=u,
                                        v=v,
                                        fun=burg_fun,
                                        fun_d=burg_fun_d)

    alpha = Material('alpha', val=[.0])
    # FluxT = AdvectDGFluxTerm("adv_lf_flux(a.val, v, u)", "a.val, v,  u[-1]",
    #                          integral, omega, u=u, v=v, a=a, alpha=alpha)

    FluxT = NonlinearHyperbolicDGFluxTerm("burgers_lf_flux(f, df, u, v)",
                                          "fun , fun_d, v, u[-1]",
                                          integral,
                                          omega,
                                          u=u,
                                          v=v,
                                          fun=burg_fun,
                                          fun_d=burg_fun_d)

    eq = Equation('balance', MassT - StiffT + FluxT)
    eqs = Equations([eq])

    # ------------------------------
    # | Create boundary conditions |
    # ------------------------------
    left_fix_u = EssentialBC('left_fix_u', left, {'u.all': 1.0})
    right_fix_u = EssentialBC('right_fix_u', right, {'u.all': 0.0})

    # ----------------------------
    # | Create initial condition |
    # ----------------------------
    def ghump(x):
        """
        Nice gaussian.
        """
        return nm.exp(-200 * x**2)

    def ic_wrap(x, ic=None):
        return ghump(x - .3)

    ic_fun = Function('ic_fun', ic_wrap)
    ics = InitialCondition('ic', omega, {'u.0': ic_fun})

    # ------------------
    # | Create problem |
    # ------------------
    pb = Problem(problem_name,
                 equations=eqs,
                 conf=Struct(options={"save_times": save_timestn},
                             ics={},
                             ebcs={},
                             epbcs={},
                             lcbcs={},
                             materials={}),
                 active_only=False)
    pb.setup_output(output_dir=output_folder, output_format=output_format)
    pb.set_ics(Conditions([ics]))

    # ------------------
    # | Create limiter |
    # ------------------
    limiter = MomentLimiter1D

    # ---------------------------
    # | Set time discretization |
    # ---------------------------
    CFL = .2
    max_velo = nm.max(nm.abs(velo))
    t0 = 0
    t1 = .2
    dx = nm.min(mesh.cmesh.get_volumes(1))
    dt = dx / max_velo * CFL / (2 * approx_order + 1)
    tn = int(nm.ceil((t1 - t0) / dt))
    dtdx = dt / dx

    # ------------------
    # | Create solver |
    # ------------------
    ls = ScipyDirect({})
    nls_status = IndexedStruct()
    nls = Newton({'is_linear': True}, lin_solver=ls, status=nls_status)

    tss_conf = {
        't0': t0,
        't1': t1,
        'n_step': tn,
        'limiters': {
            "dgfu": limiter
        }
    }

    tss = TVDRK3StepSolver(tss_conf, nls=nls, context=pb, verbose=True)

    # ---------
    # | Solve |
    # ---------
    pb.set_solver(tss)
    state_end = pb.solve()

    output("Solved equation \n\n\t\t u_t - div(f(u))) = 0\n")
    output(f"With IC: {ic_fun.name}")
    # output("and EBCs: {}".format(pb.ebcs.names))
    # output("and EPBCS: {}".format(pb.epbcs.names))
    output("-------------------------------------")
    output(f"Approximation order is {approx_order}")
    output(f"Space divided into {mesh.n_el} cells, " +
           f"{len(mesh.coors)} steps, step size is {dx}")
    output(f"Time divided into {tn - 1} nodes, {tn} steps, step size is {dt}")
    output(f"CFL coefficient was {CFL} and " +
           f"order correction {1 / (2 * approx_order + 1)}")
    output(f"Courant number c = max(abs(u)) * dt/dx = {max_velo * dtdx}")
    output("------------------------------------------")
    output(f"Time stepping solver is {tss.name}")
    output(f"Limiter used: {limiter.name}")
    output("======================================")

    # ----------
    # | Plot 1D|
    # ----------
    load_and_plot_fun(output_folder, domain_name, t0, t1,
                      min(tn, save_timestn), ic_fun)
Beispiel #31
0
def _gen_common_data(orders, gels, report):
    import sfepy
    from sfepy.base.base import Struct
    from sfepy.linalg import combine
    from sfepy.discrete import FieldVariable, Integral
    from sfepy.discrete.fem import Mesh, FEDomain, Field
    from sfepy.discrete.common.global_interp import get_ref_coors

    bases = ([ii for ii in combine([['2_4', '3_8'],
                                    ['lagrange', 'lobatto']])]
             + [ii for ii in combine([['2_3', '3_4'],
                                      ['lagrange']])])
    for geom, poly_space_base in bases:
        report('geometry: %s, base: %s' % (geom, poly_space_base))

        order = orders[geom]
        integral = Integral('i', order=order)

        aux = '' if geom in ['2_4', '3_8'] else 'z'
        mesh0 = Mesh.from_file('meshes/elements/%s_2%s.mesh' % (geom, aux),
                               prefix_dir=sfepy.data_dir)
        gel = gels[geom]

        perms = gel.get_conn_permutations()

        qps, qp_weights = integral.get_qp(gel.surface_facet.name)
        zz = nm.zeros_like(qps[:, :1])
        qps = nm.hstack(([qps] + [zz]))

        shift = shifts[geom]
        rcoors = nm.ascontiguousarray(qps
                                      + shift[:1, :] - shift[1:, :])
        ccoors = nm.ascontiguousarray(qps
                                      + shift[:1, :] + shift[1:, :])

        for ir, pr in enumerate(perms):
            for ic, pc in enumerate(perms):
                report('ir: %d, ic: %d' % (ir, ic))
                report('pr: %s, pc: %s' % (pr, pc))

                mesh = mesh0.copy()
                conn = mesh.cmesh.get_conn(mesh0.cmesh.tdim, 0).indices
                conn = conn.reshape((mesh0.n_el, -1))
                conn[0, :] = conn[0, pr]
                conn[1, :] = conn[1, pc]

                conn2 = mesh.get_conn(gel.name)
                assert_((conn == conn2).all())

                cache = Struct(mesh=mesh)

                domain = FEDomain('domain', mesh)
                omega = domain.create_region('Omega', 'all')
                region = domain.create_region('Facet', rsels[geom], 'facet')
                field = Field.from_args('f', nm.float64, shape=1,
                                        region=omega, approx_order=order,
                                        poly_space_base=poly_space_base)
                var = FieldVariable('u', 'unknown', field)
                report('# dofs: %d' % var.n_dof)

                vec = nm.empty(var.n_dof, dtype=var.dtype)

                ps = field.poly_space

                dofs = field.get_dofs_in_region(region, merge=False)
                edofs, fdofs = nm.unique(dofs[1]), nm.unique(dofs[2])

                rrc, rcells, rstatus = get_ref_coors(field, rcoors,
                                                     cache=cache)
                crc, ccells, cstatus = get_ref_coors(field, ccoors,
                                                     cache=cache)
                assert_((rstatus == 0).all() and (cstatus == 0).all())

                yield (geom, poly_space_base, qp_weights, mesh, ir, ic,
                       field, ps, rrc, rcells[0], crc, ccells[0],
                       vec, edofs, fdofs)
def create_local_problem(omega_gi, order):
    """
    Local problem definition using a domain corresponding to the global region
    `omega_gi`.
    """
    mesh = omega_gi.domain.mesh

    # All tasks have the whole mesh.
    bbox = mesh.get_bounding_box()
    min_x, max_x = bbox[:, 0]
    eps_x = 1e-8 * (max_x - min_x)

    mesh_i = Mesh.from_region(omega_gi, mesh, localize=True)
    domain_i = FEDomain('domain_i', mesh_i)
    omega_i = domain_i.create_region('Omega', 'all')

    gamma1_i = domain_i.create_region('Gamma1',
                                      'vertices in (x < %.10f)' %
                                      (min_x + eps_x),
                                      'facet',
                                      allow_empty=True)
    gamma2_i = domain_i.create_region('Gamma2',
                                      'vertices in (x > %.10f)' %
                                      (max_x - eps_x),
                                      'facet',
                                      allow_empty=True)

    field_i = Field.from_args('fu', nm.float64, 1, omega_i, approx_order=order)

    output('number of local field DOFs:', field_i.n_nod)

    u_i = FieldVariable('u_i', 'unknown', field_i)
    v_i = FieldVariable('v_i', 'test', field_i, primary_var_name='u_i')

    integral = Integral('i', order=2 * order)

    mat = Material('m', lam=10, mu=5)
    t1 = Term.new('dw_laplace(m.lam, v_i, u_i)',
                  integral,
                  omega_i,
                  m=mat,
                  v_i=v_i,
                  u_i=u_i)

    def _get_load(coors):
        val = nm.ones_like(coors[:, 0])
        for coor in coors.T:
            val *= nm.sin(4 * nm.pi * coor)
        return val

    def get_load(ts, coors, mode=None, **kwargs):
        if mode == 'qp':
            return {'val': _get_load(coors).reshape(coors.shape[0], 1, 1)}

    load = Material('load', function=Function('get_load', get_load))

    t2 = Term.new('dw_volume_lvf(load.val, v_i)',
                  integral,
                  omega_i,
                  load=load,
                  v_i=v_i)

    eq = Equation('balance', t1 - 100 * t2)
    eqs = Equations([eq])

    ebc1 = EssentialBC('ebc1', gamma1_i, {'u_i.all': 0.0})
    ebc2 = EssentialBC('ebc2', gamma2_i, {'u_i.all': 0.1})

    pb = Problem('problem_i', equations=eqs, active_only=False)
    pb.time_update(ebcs=Conditions([ebc1, ebc2]))
    pb.update_materials()

    return pb
Beispiel #33
0
def _gen_common_data(orders, gels, report):
    import sfepy
    from sfepy.base.base import Struct
    from sfepy.linalg import combine
    from sfepy.discrete import FieldVariable, Integral
    from sfepy.discrete.fem import Mesh, FEDomain, Field
    from sfepy.discrete.common.global_interp import get_ref_coors

    bases = ([ii for ii in combine([['2_4', '3_8'],
                                    ['lagrange', 'lobatto']])]
             + [ii for ii in combine([['2_3', '3_4'],
                                      ['lagrange']])])
    for geom, poly_space_base in bases:
        report('geometry: %s, base: %s' % (geom, poly_space_base))

        order = orders[geom]
        integral = Integral('i', order=order)

        aux = '' if geom in ['2_4', '3_8'] else 'z'
        mesh0 = Mesh.from_file('meshes/elements/%s_2%s.mesh' % (geom, aux),
                               prefix_dir=sfepy.data_dir)
        gel = gels[geom]

        perms = gel.get_conn_permutations()

        qps, qp_weights = integral.get_qp(gel.surface_facet.name)
        zz = nm.zeros_like(qps[:, :1])
        qps = nm.hstack(([qps] + [zz]))

        shift = shifts[geom]
        rcoors = nm.ascontiguousarray(qps
                                      + shift[:1, :] - shift[1:, :])
        ccoors = nm.ascontiguousarray(qps
                                      + shift[:1, :] + shift[1:, :])

        for ir, pr in enumerate(perms):
            for ic, pc in enumerate(perms):
                report('ir: %d, ic: %d' % (ir, ic))
                report('pr: %s, pc: %s' % (pr, pc))

                mesh = mesh0.copy()
                conn = mesh.get_conn(gel.name)
                conn[0, :] = conn[0, pr]
                conn[1, :] = conn[1, pc]

                cache = Struct(mesh=mesh)

                domain = FEDomain('domain', mesh)
                omega = domain.create_region('Omega', 'all')
                region = domain.create_region('Facet', rsels[geom], 'facet')
                field = Field.from_args('f', nm.float64, shape=1,
                                        region=omega, approx_order=order,
                                        poly_space_base=poly_space_base)
                var = FieldVariable('u', 'unknown', field)
                report('# dofs: %d' % var.n_dof)

                vec = nm.empty(var.n_dof, dtype=var.dtype)

                ap = field.ap
                ps = ap.interp.poly_spaces['v']

                dofs = field.get_dofs_in_region(region, merge=False)
                edofs, fdofs = nm.unique(dofs[1]), nm.unique(dofs[2])

                rrc, rcells, rstatus = get_ref_coors(field, rcoors,
                                                     cache=cache)
                crc, ccells, cstatus = get_ref_coors(field, ccoors,
                                                     cache=cache)
                assert_((rstatus == 0).all() and (cstatus == 0).all())

                yield (geom, poly_space_base, qp_weights, mesh, ir, ic,
                       ap, ps, rrc, rcells[0], crc, ccells[0],
                       vec, edofs, fdofs)
def main():
    from sfepy import data_dir

    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('--version', action='version', version='%(prog)s')
    parser.add_argument('--young',
                        metavar='float',
                        type=float,
                        action='store',
                        dest='young',
                        default=2000.0,
                        help=helps['young'])
    parser.add_argument('--poisson',
                        metavar='float',
                        type=float,
                        action='store',
                        dest='poisson',
                        default=0.4,
                        help=helps['poisson'])
    parser.add_argument('--load',
                        metavar='float',
                        type=float,
                        action='store',
                        dest='load',
                        default=-1000.0,
                        help=helps['load'])
    parser.add_argument('--order',
                        metavar='int',
                        type=int,
                        action='store',
                        dest='order',
                        default=1,
                        help=helps['order'])
    parser.add_argument('-r',
                        '--refine',
                        metavar='int',
                        type=int,
                        action='store',
                        dest='refine',
                        default=0,
                        help=helps['refine'])
    parser.add_argument('-s',
                        '--show',
                        action="store_true",
                        dest='show',
                        default=False,
                        help=helps['show'])
    parser.add_argument('-p',
                        '--probe',
                        action="store_true",
                        dest='probe',
                        default=False,
                        help=helps['probe'])
    options = parser.parse_args()

    assert_((0.0 < options.poisson < 0.5),
            "Poisson's ratio must be in ]0, 0.5[!")
    assert_((0 < options.order),
            'displacement approximation order must be at least 1!')

    output('using values:')
    output("  Young's modulus:", options.young)
    output("  Poisson's ratio:", options.poisson)
    output('  vertical load:', options.load)
    output('uniform mesh refinement level:', options.refine)

    # Build the problem definition.
    mesh = Mesh.from_file(data_dir + '/meshes/2d/its2D.mesh')
    domain = FEDomain('domain', mesh)

    if options.refine > 0:
        for ii in range(options.refine):
            output('refine %d...' % ii)
            domain = domain.refine()
            output('... %d nodes %d elements' %
                   (domain.shape.n_nod, domain.shape.n_el))

    omega = domain.create_region('Omega', 'all')
    left = domain.create_region('Left', 'vertices in x < 0.001', 'facet')
    bottom = domain.create_region('Bottom', 'vertices in y < 0.001', 'facet')
    top = domain.create_region('Top', 'vertex 2', 'vertex')

    field = Field.from_args('fu',
                            nm.float64,
                            'vector',
                            omega,
                            approx_order=options.order)

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

    D = stiffness_from_youngpoisson(2, options.young, options.poisson)

    asphalt = Material('Asphalt', D=D)
    load = Material('Load', values={'.val': [0.0, options.load]})

    integral = Integral('i', order=2 * options.order)
    integral0 = Integral('i', order=0)

    t1 = Term.new('dw_lin_elastic(Asphalt.D, v, u)',
                  integral,
                  omega,
                  Asphalt=asphalt,
                  v=v,
                  u=u)
    t2 = Term.new('dw_point_load(Load.val, v)', integral0, top, Load=load, v=v)
    eq = Equation('balance', t1 - t2)
    eqs = Equations([eq])

    xsym = EssentialBC('XSym', bottom, {'u.1': 0.0})
    ysym = EssentialBC('YSym', left, {'u.0': 0.0})

    ls = AutoDirect({})

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

    pb = Problem('elasticity', equations=eqs)

    pb.set_bcs(ebcs=Conditions([xsym, ysym]))

    pb.set_solver(nls)

    # Solve the problem.
    state = pb.solve()
    output(nls_status)

    # Postprocess the solution.
    out = state.create_output_dict()
    out = stress_strain(out, pb, state, extend=True)
    pb.save_state('its2D_interactive.vtk', out=out)

    gdata = geometry_data['2_3']
    nc = len(gdata.coors)

    integral_vn = Integral('ivn',
                           coors=gdata.coors,
                           weights=[gdata.volume / nc] * nc)

    nodal_stress(out, pb, state, integrals=Integrals([integral_vn]))

    if options.probe:
        # Probe the solution.
        probes, labels = gen_lines(pb)

        sfield = Field.from_args('sym_tensor',
                                 nm.float64,
                                 3,
                                 omega,
                                 approx_order=options.order - 1)
        stress = FieldVariable('stress',
                               'parameter',
                               sfield,
                               primary_var_name='(set-to-None)')
        strain = FieldVariable('strain',
                               'parameter',
                               sfield,
                               primary_var_name='(set-to-None)')

        cfield = Field.from_args('component',
                                 nm.float64,
                                 1,
                                 omega,
                                 approx_order=options.order - 1)
        component = FieldVariable('component',
                                  'parameter',
                                  cfield,
                                  primary_var_name='(set-to-None)')

        ev = pb.evaluate
        order = 2 * (options.order - 1)
        strain_qp = ev('ev_cauchy_strain.%d.Omega(u)' % order, mode='qp')
        stress_qp = ev('ev_cauchy_stress.%d.Omega(Asphalt.D, u)' % order,
                       mode='qp',
                       copy_materials=False)

        project_by_component(strain, strain_qp, component, order)
        project_by_component(stress, stress_qp, component, order)

        all_results = []
        for ii, probe in enumerate(probes):
            fig, results = probe_results(u, strain, stress, probe, labels[ii])

            fig.savefig('its2D_interactive_probe_%d.png' % ii)
            all_results.append(results)

        for ii, results in enumerate(all_results):
            output('probe %d:' % ii)
            output.level += 2
            for key, res in ordered_iteritems(results):
                output(key + ':')
                val = res[1]
                output('  min: %+.2e, mean: %+.2e, max: %+.2e' %
                       (val.min(), val.mean(), val.max()))
            output.level -= 2

    if options.show:
        # Show the solution. If the approximation order is greater than 1, the
        # extra DOFs are simply thrown away.
        from sfepy.postprocess.viewer import Viewer

        view = Viewer('its2D_interactive.vtk')
        view(vector_mode='warp_norm',
             rel_scaling=1,
             is_scalar_bar=True,
             is_wireframe=True)
def main(cli_args):
    dims = parse_argument_list(cli_args.dims, float)
    shape = parse_argument_list(cli_args.shape, int)
    centre = parse_argument_list(cli_args.centre, float)
    material_parameters = parse_argument_list(cli_args.material_parameters,
                                              float)
    order = cli_args.order

    ts_vals = cli_args.ts.split(',')
    ts = {
        't0' : float(ts_vals[0]), 't1' : float(ts_vals[1]),
        'n_step' : int(ts_vals[2])}

    do_plot = cli_args.plot

    ### Mesh and regions ###
    mesh = gen_block_mesh(
        dims, shape, centre, name='block', verbose=False)
    domain = FEDomain('domain', mesh)

    omega = domain.create_region('Omega', 'all')

    lbn, rtf = domain.get_mesh_bounding_box()
    box_regions = define_box_regions(3, lbn, rtf)
    regions = dict([
        [r, domain.create_region(r, box_regions[r][0], box_regions[r][1])]
        for r in box_regions])

    ### Fields ###
    scalar_field = Field.from_args(
        'fu', np.float64, 'scalar', omega, approx_order=order-1)
    vector_field = Field.from_args(
        'fv', np.float64, 'vector', omega, approx_order=order)

    u = FieldVariable('u', 'unknown', vector_field, history=1)
    v = FieldVariable('v', 'test', vector_field, primary_var_name='u')
    p = FieldVariable('p', 'unknown', scalar_field, history=1)
    q = FieldVariable('q', 'test', scalar_field, primary_var_name='p')

    ### Material ###
    c10, c01 = material_parameters
    m = Material(
        'm', mu=2*c10, kappa=2*c01,
    )

    ### Boundary conditions ###
    x_sym = EssentialBC('x_sym', regions['Left'], {'u.0' : 0.0})
    y_sym = EssentialBC('y_sym', regions['Near'], {'u.1' : 0.0})
    z_sym = EssentialBC('z_sym', regions['Bottom'], {'u.2' : 0.0})
    disp_fun = Function('disp_fun', get_displacement)
    displacement = EssentialBC(
        'displacement', regions['Right'], {'u.0' : disp_fun})
    ebcs = Conditions([x_sym, y_sym, z_sym, displacement])

    ### Terms and equations ###
    integral = Integral('i', order=2*order)

    term_neohook = Term.new(
        'dw_tl_he_neohook(m.mu, v, u)',
        integral, omega, m=m, v=v, u=u)
    term_mooney = Term.new(
        'dw_tl_he_mooney_rivlin(m.kappa, v, u)',
        integral, omega, m=m, v=v, u=u)
    term_pressure = Term.new(
        'dw_tl_bulk_pressure(v, u, p)',
        integral, omega, v=v, u=u, p=p)

    term_volume_change = Term.new(
        'dw_tl_volume(q, u)',
        integral, omega, q=q, u=u, term_mode='volume')
    term_volume = Term.new(
        'dw_volume_integrate(q)',
        integral, omega, q=q)

    eq_balance = Equation('balance', term_neohook+term_mooney+term_pressure)
    eq_volume = Equation('volume', term_volume_change-term_volume)
    equations = Equations([eq_balance, eq_volume])

    ### Solvers ###
    ls = ScipyDirect({})
    nls_status = IndexedStruct()
    nls = Newton(
        {'i_max' : 5},
        lin_solver=ls, status=nls_status
    )

    ### Problem ###
    pb = Problem('hyper', equations=equations)
    pb.set_bcs(ebcs=ebcs)
    pb.set_ics(ics=Conditions([]))
    tss = SimpleTimeSteppingSolver(ts, nls=nls, context=pb)
    pb.set_solver(tss)

    ### Solution ###
    axial_stress = []
    axial_displacement = []
    def stress_strain_fun(*args, **kwargs):
        return stress_strain(
            *args, order=order, global_stress=axial_stress,
            global_displacement=axial_displacement, **kwargs)

    pb.solve(save_results=True, post_process_hook=stress_strain_fun)

    if do_plot:
        plot_graphs(
            material_parameters, axial_stress, axial_displacement,
            undeformed_length=dims[0])
Beispiel #36
0
def save_basis_on_mesh(mesh, options, output_dir, lin,
                       permutations=None, suffix=''):
    if permutations is not None:
        mesh = mesh.copy()
        gel = GeometryElement(mesh.descs[0])
        perms = gel.get_conn_permutations()[permutations]
        conn = mesh.cmesh.get_cell_conn()
        n_el, n_ep = conn.num, gel.n_vertex
        offsets = nm.arange(n_el) * n_ep

        conn.indices[:] = conn.indices.take((perms + offsets[:, None]).ravel())

    domain = FEDomain('domain', mesh)

    omega = domain.create_region('Omega', 'all')
    field = Field.from_args('f', nm.float64, shape=1, region=omega,
                            approx_order=options.max_order,
                            poly_space_base=options.basis)
    var = FieldVariable('u', 'unknown', field)

    if options.plot_dofs:
        import sfepy.postprocess.plot_dofs as pd
        import sfepy.postprocess.plot_cmesh as pc
        ax = pc.plot_wireframe(None, mesh.cmesh)
        ax = pd.plot_global_dofs(ax, field.get_coor(), field.econn)
        ax = pd.plot_local_dofs(ax, field.get_coor(), field.econn)
        if options.dofs is not None:
            ax = pd.plot_nodes(ax, field.get_coor(), field.econn,
                               field.poly_space.nodes,
                               get_dofs(options.dofs, var.n_dof))
        pd.plt.show()

    output('dofs: %d' % var.n_dof)

    vec = nm.empty(var.n_dof, dtype=var.dtype)
    n_digit, _format = get_print_info(var.n_dof, fill='0')
    name_template = os.path.join(output_dir,
                                 'dof_%s%s.vtk' % (_format, suffix))
    for ip in get_dofs(options.dofs, var.n_dof):
        output('dof %d...' % ip)

        vec.fill(0.0)
        vec[ip] = 1.0

        var.set_data(vec)

        if options.derivative == 0:
            out = var.create_output(vec, linearization=lin)

        else:
            out = create_expression_output('ev_grad.ie.Elements(u)',
                                           'u', 'f', {'f' : field}, None,
                                           Variables([var]),
                                           mode='qp', verbose=False,
                                           min_level=lin.min_level,
                                           max_level=lin.max_level,
                                           eps=lin.eps)

        name = name_template % ip
        ensure_path(name)
        out['u'].mesh.write(name, out=out)

        output('...done (%s)' % name)
Beispiel #37
0
def main():
    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('--version', action='version', version='%(prog)s')
    parser.add_argument('-d', '--dims', metavar='dims',
                        action='store', dest='dims',
                        default='[1.0, 1.0]', help=helps['dims'])
    parser.add_argument('-c', '--centre', metavar='centre',
                        action='store', dest='centre',
                        default='[0.0, 0.0]', help=helps['centre'])
    parser.add_argument('-s', '--shape', metavar='shape',
                        action='store', dest='shape',
                        default='[11, 11]', help=helps['shape'])
    parser.add_argument('-b', '--bc-kind', metavar='kind',
                        action='store', dest='bc_kind',
                        choices=['free', 'cantilever', 'fixed'],
                        default='free', help=helps['bc_kind'])
    parser.add_argument('-a', '--axis', metavar='0, ..., dim, or -1',
                        type=int, action='store', dest='axis',
                        default=-1, help=helps['axis'])
    parser.add_argument('--young', metavar='float', type=float,
                        action='store', dest='young',
                        default=6.80e+10, help=helps['young'])
    parser.add_argument('--poisson', metavar='float', type=float,
                        action='store', dest='poisson',
                        default=0.36, help=helps['poisson'])
    parser.add_argument('--density', metavar='float', type=float,
                        action='store', dest='density',
                        default=2700.0, help=helps['density'])
    parser.add_argument('--order', metavar='int', type=int,
                        action='store', dest='order',
                        default=1, help=helps['order'])
    parser.add_argument('-n', '--n-eigs', metavar='int', type=int,
                        action='store', dest='n_eigs',
                        default=6, help=helps['n_eigs'])
    parser.add_argument('-i', '--ignore', metavar='int', type=int,
                        action='store', dest='ignore',
                        default=None, help=helps['ignore'])
    parser.add_argument('--solver', metavar='solver', action='store',
                        dest='solver',
                        default= \
                        "eig.scipy,method:'eigh',tol:1e-5,maxiter:1000",
                        help=helps['solver'])
    parser.add_argument('--show',
                        action="store_true", dest='show',
                        default=False, help=helps['show'])
    parser.add_argument('filename', nargs='?', default=None)
    options = parser.parse_args()

    aux = options.solver.split(',')
    kwargs = {}
    for option in aux[1:]:
        key, val = option.split(':')
        kwargs[key.strip()] = eval(val)
    eig_conf = Struct(name='evp', kind=aux[0], **kwargs)

    output('using values:')
    output("  Young's modulus:", options.young)
    output("  Poisson's ratio:", options.poisson)
    output('  density:', options.density)
    output('displacement field approximation order:', options.order)
    output('requested %d eigenvalues' % options.n_eigs)
    output('using eigenvalue problem solver:', eig_conf.kind)
    output.level += 1
    for key, val in six.iteritems(kwargs):
        output('%s: %r' % (key, val))
    output.level -= 1

    assert_((0.0 < options.poisson < 0.5),
            "Poisson's ratio must be in ]0, 0.5[!")
    assert_((0 < options.order),
            'displacement approximation order must be at least 1!')

    filename = options.filename
    if filename is not None:
        mesh = Mesh.from_file(filename)
        dim = mesh.dim
        dims = nm.diff(mesh.get_bounding_box(), axis=0)

    else:
        dims = nm.array(eval(options.dims), dtype=nm.float64)
        dim = len(dims)

        centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim]
        shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim]

        output('dimensions:', dims)
        output('centre:    ', centre)
        output('shape:     ', shape)

        mesh = gen_block_mesh(dims, shape, centre, name='mesh')

    output('axis:      ', options.axis)
    assert_((-dim <= options.axis < dim), 'invalid axis value!')

    eig_solver = Solver.any_from_conf(eig_conf)

    # Build the problem definition.
    domain = FEDomain('domain', mesh)

    bbox = domain.get_mesh_bounding_box()
    min_coor, max_coor = bbox[:, options.axis]
    eps = 1e-8 * (max_coor - min_coor)
    ax = 'xyz'[:dim][options.axis]

    omega = domain.create_region('Omega', 'all')
    bottom = domain.create_region('Bottom',
                                  'vertices in (%s < %.10f)'
                                  % (ax, min_coor + eps),
                                  'facet')
    bottom_top = domain.create_region('BottomTop',
                                      'r.Bottom +v vertices in (%s > %.10f)'
                                      % (ax, max_coor - eps),
                                      'facet')

    field = Field.from_args('fu', nm.float64, 'vector', omega,
                            approx_order=options.order)

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

    mtx_d = stiffness_from_youngpoisson(dim, options.young, options.poisson)

    m = Material('m', D=mtx_d, rho=options.density)

    integral = Integral('i', order=2*options.order)

    t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u)
    t2 = Term.new('dw_volume_dot(m.rho, v, u)', integral, omega, m=m, v=v, u=u)
    eq1 = Equation('stiffness', t1)
    eq2 = Equation('mass', t2)
    lhs_eqs = Equations([eq1, eq2])

    pb = Problem('modal', equations=lhs_eqs)

    if options.bc_kind == 'free':
        pb.time_update()
        n_rbm = dim * (dim + 1) // 2

    elif options.bc_kind == 'cantilever':
        fixed = EssentialBC('Fixed', bottom, {'u.all' : 0.0})
        pb.time_update(ebcs=Conditions([fixed]))
        n_rbm = 0

    elif options.bc_kind == 'fixed':
        fixed = EssentialBC('Fixed', bottom_top, {'u.all' : 0.0})
        pb.time_update(ebcs=Conditions([fixed]))
        n_rbm = 0

    else:
        raise ValueError('unsupported BC kind! (%s)' % options.bc_kind)

    if options.ignore is not None:
        n_rbm = options.ignore

    pb.update_materials()

    # Assemble stiffness and mass matrices.
    mtx_k = eq1.evaluate(mode='weak', dw_mode='matrix', asm_obj=pb.mtx_a)
    mtx_m = mtx_k.copy()
    mtx_m.data[:] = 0.0
    mtx_m = eq2.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m)

    try:
        eigs, svecs = eig_solver(mtx_k, mtx_m, options.n_eigs + n_rbm,
                                 eigenvectors=True)

    except sla.ArpackNoConvergence as ee:
        eigs = ee.eigenvalues
        svecs = ee.eigenvectors
        output('only %d eigenvalues converged!' % len(eigs))

    output('%d eigenvalues converged (%d ignored as rigid body modes)' %
           (len(eigs), n_rbm))

    eigs = eigs[n_rbm:]
    svecs = svecs[:, n_rbm:]

    omegas = nm.sqrt(eigs)
    freqs = omegas / (2 * nm.pi)

    output('number |         eigenvalue |  angular frequency '
           '|          frequency')
    for ii, eig in enumerate(eigs):
        output('%6d | %17.12e | %17.12e | %17.12e'
               % (ii + 1, eig, omegas[ii], freqs[ii]))

    # Make full eigenvectors (add DOFs fixed by boundary conditions).
    variables = pb.get_variables()

    vecs = nm.empty((variables.di.ptr[-1], svecs.shape[1]),
                    dtype=nm.float64)
    for ii in range(svecs.shape[1]):
        vecs[:, ii] = variables.make_full_vec(svecs[:, ii])

    # Save the eigenvectors.
    out = {}
    state = pb.create_state()
    for ii in range(eigs.shape[0]):
        state.set_full(vecs[:, ii])
        aux = state.create_output_dict()
        strain = pb.evaluate('ev_cauchy_strain.i.Omega(u)',
                             integrals=Integrals([integral]),
                             mode='el_avg', verbose=False)
        out['u%03d' % ii] = aux.popitem()[1]
        out['strain%03d' % ii] = Struct(mode='cell', data=strain)

    pb.save_state('eigenshapes.vtk', out=out)
    pb.save_regions_as_groups('regions')

    if len(eigs) and options.show:
        # Show the solution. If the approximation order is greater than 1, the
        # extra DOFs are simply thrown away.
        from sfepy.postprocess.viewer import Viewer
        from sfepy.postprocess.domain_specific import DomainSpecificPlot

        scaling = 0.05 * dims.max() / nm.abs(vecs).max()

        ds = {}
        for ii in range(eigs.shape[0]):
            pd = DomainSpecificPlot('plot_displacements',
                                    ['rel_scaling=%s' % scaling,
                                     'color_kind="tensors"',
                                     'color_name="strain%03d"' % ii])
            ds['u%03d' % ii] = pd

        view = Viewer('eigenshapes.vtk')
        view(domain_specific=ds, only_names=sorted(ds.keys()),
             is_scalar_bar=False, is_wireframe=True)
def solve_problem(mesh_filename, options, comm):
    order_u = options.order_u
    order_p = options.order_p

    rank, size = comm.Get_rank(), comm.Get_size()

    output('rank', rank, 'of', size)

    mesh = Mesh.from_file(mesh_filename)

    if rank == 0:
        cell_tasks = pl.partition_mesh(mesh,
                                       size,
                                       use_metis=options.metis,
                                       verbose=True)

    else:
        cell_tasks = None

    output('creating global domain and fields...')
    tt = time.clock()
    domain = FEDomain('domain', mesh)
    omega = domain.create_region('Omega', 'all')
    field1 = Field.from_args('fu',
                             nm.float64,
                             mesh.dim,
                             omega,
                             approx_order=order_u)
    field2 = Field.from_args('fp', nm.float64, 1, omega, approx_order=order_p)
    fields = [field1, field2]
    output('...done in', time.clock() - tt)

    output('distributing fields...')
    tt = time.clock()

    distribute = pl.distribute_fields_dofs
    lfds, gfds = distribute(fields,
                            cell_tasks,
                            is_overlap=True,
                            use_expand_dofs=True,
                            save_inter_regions=options.save_inter_regions,
                            output_dir=options.output_dir,
                            comm=comm,
                            verbose=True)

    output('...done in', time.clock() - tt)

    output('creating local problem...')
    tt = time.clock()

    cells = lfds[0].cells

    omega_gi = Region.from_cells(cells, domain)
    omega_gi.finalize()
    omega_gi.update_shape()

    pb = create_local_problem(omega_gi, [order_u, order_p])

    variables = pb.get_variables()

    state = State(variables)
    state.fill(0.0)
    state.apply_ebc()

    output('...done in', time.clock() - tt)

    output('allocating global system...')
    tt = time.clock()

    sizes, drange, pdofs = pl.setup_composite_dofs(lfds,
                                                   fields,
                                                   variables,
                                                   verbose=True)
    pmtx, psol, prhs = pl.create_petsc_system(pb.mtx_a,
                                              sizes,
                                              pdofs,
                                              drange,
                                              is_overlap=True,
                                              comm=comm,
                                              verbose=True)

    output('...done in', time.clock() - tt)

    output('creating solver...')
    tt = time.clock()

    conf = Struct(method='bcgsl',
                  precond='jacobi',
                  sub_precond='none',
                  i_max=10000,
                  eps_a=1e-50,
                  eps_r=1e-6,
                  eps_d=1e4,
                  verbose=True)
    status = {}
    ls = PETScKrylovSolver(conf, comm=comm, mtx=pmtx, status=status)

    field_ranges = {}
    for ii, variable in enumerate(variables.iter_state(ordered=True)):
        field_ranges[variable.name] = lfds[ii].petsc_dofs_range

    ls.set_field_split(field_ranges, comm=comm)

    ev = PETScParallelEvaluator(pb,
                                pdofs,
                                drange,
                                True,
                                psol,
                                comm,
                                verbose=True)

    nls_status = {}
    conf = Struct(method='newtonls',
                  i_max=5,
                  eps_a=0,
                  eps_r=1e-5,
                  eps_s=0.0,
                  verbose=True)
    nls = PETScNonlinearSolver(conf,
                               pmtx=pmtx,
                               prhs=prhs,
                               comm=comm,
                               fun=ev.eval_residual,
                               fun_grad=ev.eval_tangent_matrix,
                               lin_solver=ls,
                               status=nls_status)

    output('...done in', time.clock() - tt)

    output('solving...')
    tt = time.clock()

    state = pb.create_state()
    state.apply_ebc()

    ev.psol_i[...] = state()
    ev.gather(psol, ev.psol_i)

    psol = nls(psol)

    ev.scatter(ev.psol_i, psol)
    sol0_i = ev.psol_i[...]

    output('...done in', time.clock() - tt)

    output('saving solution...')
    tt = time.clock()

    state.set_full(sol0_i)
    out = state.create_output_dict()

    filename = os.path.join(options.output_dir, 'sol_%02d.h5' % comm.rank)
    pb.domain.mesh.write(filename, io='auto', out=out)

    gather_to_zero = pl.create_gather_to_zero(psol)

    psol_full = gather_to_zero(psol)

    if comm.rank == 0:
        sol = psol_full[...].copy()

        u = FieldVariable('u',
                          'parameter',
                          field1,
                          primary_var_name='(set-to-None)')
        remap = gfds[0].id_map
        ug = sol[remap]

        p = FieldVariable('p',
                          'parameter',
                          field2,
                          primary_var_name='(set-to-None)')
        remap = gfds[1].id_map
        pg = sol[remap]

        if (((order_u == 1) and (order_p == 1))
                or (options.linearization == 'strip')):
            out = u.create_output(ug)
            out.update(p.create_output(pg))
            filename = os.path.join(options.output_dir, 'sol.h5')
            mesh.write(filename, io='auto', out=out)

        else:
            out = u.create_output(ug,
                                  linearization=Struct(kind='adaptive',
                                                       min_level=0,
                                                       max_level=order_u,
                                                       eps=1e-3))

            filename = os.path.join(options.output_dir, 'sol_u.h5')
            out['u'].mesh.write(filename, io='auto', out=out)

            out = p.create_output(pg,
                                  linearization=Struct(kind='adaptive',
                                                       min_level=0,
                                                       max_level=order_p,
                                                       eps=1e-3))

            filename = os.path.join(options.output_dir, 'sol_p.h5')
            out['p'].mesh.write(filename, io='auto', out=out)

    output('...done in', time.clock() - tt)
Beispiel #39
0
def solve_problem(mesh_filename, options, comm):
    order = options.order

    rank, size = comm.Get_rank(), comm.Get_size()

    output('rank', rank, 'of', size)

    mesh = Mesh.from_file(mesh_filename)

    if rank == 0:
        cell_tasks = pl.partition_mesh(mesh, size, use_metis=options.metis,
                                       verbose=True)

    else:
        cell_tasks = None

    domain = FEDomain('domain', mesh)
    omega = domain.create_region('Omega', 'all')
    field = Field.from_args('fu', nm.float64, 1, omega, approx_order=order)

    output('distributing field %s...' % field.name)
    tt = time.clock()

    distribute = pl.distribute_fields_dofs
    lfds, gfds = distribute([field], cell_tasks,
                            is_overlap=True,
                            save_inter_regions=options.save_inter_regions,
                            output_dir=options.output_dir,
                            comm=comm, verbose=True)
    lfd = lfds[0]

    output('...done in', time.clock() - tt)

    if rank == 0:
        dof_maps = gfds[0].dof_maps
        id_map = gfds[0].id_map

        if options.verify:
            verify_save_dof_maps(field, cell_tasks,
                                 dof_maps, id_map, options, verbose=True)

        if options.plot:
            ppd.plot_partitioning([None, None], field, cell_tasks, gfds[0],
                                  options.output_dir, size)

    output('creating local problem...')
    tt = time.clock()

    omega_gi = Region.from_cells(lfd.cells, field.domain)
    omega_gi.finalize()
    omega_gi.update_shape()

    pb = create_local_problem(omega_gi, order)

    output('...done in', time.clock() - tt)

    variables = pb.get_variables()
    eqs = pb.equations

    u_i = variables['u_i']
    field_i = u_i.field

    if options.plot:
        ppd.plot_local_dofs([None, None], field, field_i, omega_gi,
                            options.output_dir, rank)

    output('allocating global system...')
    tt = time.clock()

    sizes, drange = pl.get_sizes(lfd.petsc_dofs_range, field.n_nod, 1)
    output('sizes:', sizes)
    output('drange:', drange)

    pdofs = pl.get_local_ordering(field_i, lfd.petsc_dofs_conn)

    output('pdofs:', pdofs)

    pmtx, psol, prhs = pl.create_petsc_system(pb.mtx_a, sizes, pdofs, drange,
                                              is_overlap=True, comm=comm,
                                              verbose=True)

    output('...done in', time.clock() - tt)

    output('evaluating local problem...')
    tt = time.clock()

    state = State(variables)
    state.fill(0.0)
    state.apply_ebc()

    rhs_i = eqs.eval_residuals(state())
    # This must be after pl.create_petsc_system() call!
    mtx_i = eqs.eval_tangent_matrices(state(), pb.mtx_a)

    output('...done in', time.clock() - tt)

    output('assembling global system...')
    tt = time.clock()

    pl.apply_ebc_to_matrix(mtx_i, u_i.eq_map.eq_ebc)
    pl.assemble_rhs_to_petsc(prhs, rhs_i, pdofs, drange, is_overlap=True,
                             comm=comm, verbose=True)
    pl.assemble_mtx_to_petsc(pmtx, mtx_i, pdofs, drange, is_overlap=True,
                             comm=comm, verbose=True)

    output('...done in', time.clock() - tt)

    output('creating solver...')
    tt = time.clock()

    conf = Struct(method='cg', precond='gamg', sub_precond=None,
                  i_max=10000, eps_a=1e-50, eps_r=1e-5, eps_d=1e4, verbose=True)
    status = {}
    ls = PETScKrylovSolver(conf, comm=comm, mtx=pmtx, status=status)

    output('...done in', time.clock() - tt)

    output('solving...')
    tt = time.clock()

    psol = ls(prhs, psol, conf)

    psol_i = pl.create_local_petsc_vector(pdofs)
    gather, scatter = pl.create_gather_scatter(pdofs, psol_i, psol, comm=comm)

    scatter(psol_i, psol)

    sol0_i = state() - psol_i[...]
    psol_i[...] = sol0_i

    gather(psol, psol_i)

    output('...done in', time.clock() - tt)

    output('saving solution...')
    tt = time.clock()

    u_i.set_data(sol0_i)
    out = u_i.create_output()

    filename = os.path.join(options.output_dir, 'sol_%02d.h5' % comm.rank)
    pb.domain.mesh.write(filename, io='auto', out=out)

    gather_to_zero = pl.create_gather_to_zero(psol)

    psol_full = gather_to_zero(psol)

    if comm.rank == 0:
        sol = psol_full[...].copy()[id_map]

        u = FieldVariable('u', 'parameter', field,
                          primary_var_name='(set-to-None)')

        filename = os.path.join(options.output_dir, 'sol.h5')
        if (order == 1) or (options.linearization == 'strip'):
            out = u.create_output(sol)
            mesh.write(filename, io='auto', out=out)

        else:
            out = u.create_output(sol, linearization=Struct(kind='adaptive',
                                                            min_level=0,
                                                            max_level=order,
                                                            eps=1e-3))

            out['u'].mesh.write(filename, io='auto', out=out)

    output('...done in', time.clock() - tt)

    if options.show:
        plt.show()
Beispiel #40
0
def main():
    parser = OptionParser(usage=usage, version="%prog " + sfepy.__version__)
    parser.add_option("-m",
                      "--mesh",
                      action="store_true",
                      dest="save_mesh",
                      default=False,
                      help="save surface mesh")
    parser.add_option("-n",
                      "--no-surface",
                      action="store_true",
                      dest="no_surface",
                      default=False,
                      help="do not output surface [default: %default]")
    (options, args) = parser.parse_args()

    if (len(args) == 2):
        filename_in = args[0]
        filename_out = args[1]
    else:
        parser.print_help(),
        return

    if (filename_in == '-'):
        file_in = sys.stdin
    else:
        file_in = open(filename_in, "r")

    mesh = Mesh.from_file(filename_in)

    if (filename_in != '-'):
        file_in.close()

    domain = FEDomain('domain', mesh)

    if options.save_mesh:
        region = domain.create_region('surf', 'vertices of surface', 'facet')
        surf_mesh = Mesh.from_region(region,
                                     mesh,
                                     localize=True,
                                     is_surface=True)
        aux = edit_filename(filename_in, prefix='surf_', new_ext='.mesh')
        surf_mesh.write(aux, io='auto')

    if domain.has_faces():
        domain.fix_element_orientation()

        lst, surf_faces = get_surface_faces(domain)

        if options.no_surface:
            return

        gr_s = surface_graph(surf_faces, mesh.n_nod)

        n_comp, comps = surface_components(gr_s, surf_faces)
        output('number of surface components:', n_comp)

        ccs, comps = comps, nm.zeros((0, 1), nm.int32)
        for cc in ccs:
            comps = nm.concatenate((comps, cc[:, nm.newaxis]), 0)

        out = nm.concatenate((lst, comps), 1)

        if (filename_out == '-'):
            file_out = sys.stdout
        else:
            file_out = open(filename_out, "w")
        for row in out:
            file_out.write('%d %d %d\n' % (row[0], row[1], row[2]))
        if (filename_out != '-'):
            file_out.close()
def create_local_problem(omega_gi, orders):
    """
    Local problem definition using a domain corresponding to the global region
    `omega_gi`.
    """
    order_u, order_p = orders

    mesh = omega_gi.domain.mesh

    # All tasks have the whole mesh.
    bbox = mesh.get_bounding_box()
    min_x, max_x = bbox[:, 0]
    eps_x = 1e-8 * (max_x - min_x)

    min_y, max_y = bbox[:, 1]
    eps_y = 1e-8 * (max_y - min_y)

    mesh_i = Mesh.from_region(omega_gi, mesh, localize=True)
    domain_i = FEDomain('domain_i', mesh_i)
    omega_i = domain_i.create_region('Omega', 'all')

    gamma1_i = domain_i.create_region('Gamma1',
                                      'vertices in (x < %.10f)'
                                      % (min_x + eps_x),
                                      'facet', allow_empty=True)
    gamma2_i = domain_i.create_region('Gamma2',
                                      'vertices in (x > %.10f)'
                                      % (max_x - eps_x),
                                      'facet', allow_empty=True)
    gamma3_i = domain_i.create_region('Gamma3',
                                      'vertices in (y < %.10f)'
                                      % (min_y + eps_y),
                                      'facet', allow_empty=True)

    field1_i = Field.from_args('fu', nm.float64, mesh.dim, omega_i,
                               approx_order=order_u)

    field2_i = Field.from_args('fp', nm.float64, 1, omega_i,
                               approx_order=order_p)

    output('field 1: number of local DOFs:', field1_i.n_nod)
    output('field 2: number of local DOFs:', field2_i.n_nod)

    u_i = FieldVariable('u_i', 'unknown', field1_i, order=0)
    v_i = FieldVariable('v_i', 'test', field1_i, primary_var_name='u_i')
    p_i = FieldVariable('p_i', 'unknown', field2_i, order=1)
    q_i = FieldVariable('q_i', 'test', field2_i, primary_var_name='p_i')

    if mesh.dim == 2:
        alpha = 1e2 * nm.array([[0.132], [0.132], [0.092]])

    else:
        alpha = 1e2 * nm.array([[0.132], [0.132], [0.132],
                                [0.092], [0.092], [0.092]])

    mat = Material('m', D=stiffness_from_lame(mesh.dim, lam=10, mu=5),
                   k=1, alpha=alpha)
    integral = Integral('i', order=2*(max(order_u, order_p)))

    t11 = Term.new('dw_lin_elastic(m.D, v_i, u_i)',
                   integral, omega_i, m=mat, v_i=v_i, u_i=u_i)
    t12 = Term.new('dw_biot(m.alpha, v_i, p_i)',
                   integral, omega_i, m=mat, v_i=v_i, p_i=p_i)
    t21 = Term.new('dw_biot(m.alpha, u_i, q_i)',
                   integral, omega_i, m=mat, u_i=u_i, q_i=q_i)
    t22 = Term.new('dw_laplace(m.k, q_i, p_i)',
                   integral, omega_i, m=mat, q_i=q_i, p_i=p_i)

    eq1 = Equation('eq1', t11 - t12)
    eq2 = Equation('eq1', t21 + t22)
    eqs = Equations([eq1, eq2])

    ebc1 = EssentialBC('ebc1', gamma1_i, {'u_i.all' : 0.0})
    ebc2 = EssentialBC('ebc2', gamma2_i, {'u_i.0' : 0.05})
    def bc_fun(ts, coors, **kwargs):
        val = 0.3 * nm.sin(4 * nm.pi * (coors[:, 0] - min_x) / (max_x - min_x))
        return val

    fun = Function('bc_fun', bc_fun)
    ebc3 = EssentialBC('ebc3', gamma3_i, {'p_i.all' : fun})

    pb = Problem('problem_i', equations=eqs, active_only=False)
    pb.time_update(ebcs=Conditions([ebc1, ebc2, ebc3]))
    pb.update_materials()

    return pb
Beispiel #42
0
n_nod = 100
n_el = n_nod - 1
coors = nm.linspace(X1, XN, n_nod).reshape((n_nod, 1))
conn = nm.arange(n_nod, dtype=nm.int32).repeat(2)[1:-1].reshape((-1, 2))
mat_ids = nm.zeros(n_nod - 1, dtype=nm.int32)
descs = ['1_2']
mesh = Mesh.from_data('uniform_1D{}'.format(n_nod), coors, None, [conn],
                      [mat_ids], descs)

# -----------------------------
# | Create problem components |
# -----------------------------

integral = Integral('i', order=approx_order * 2)
domain = FEDomain(domain_name, mesh)
omega = domain.create_region('Omega', 'all')
left = domain.create_region('Gamma1', 'vertices in x == %.10f' % X1, 'vertex')
right = domain.create_region('Gamma2', 'vertices in x == %.10f' % XN, 'vertex')
field = DGField('dgfu', nm.float64, 'scalar', omega, approx_order=approx_order)

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

MassT = DotProductVolumeTerm("adv_vol(v, u)",
                             "v, u",
                             integral,
                             omega,
                             u=u,
                             v=v)

velo = nm.array(1.0)
Beispiel #43
0
def main():
    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('--version', action='version', version='%(prog)s')
    parser.add_argument('-d', '--dims', metavar='dims',
                        action='store', dest='dims',
                        default='[1.0, 1.0]', help=helps['dims'])
    parser.add_argument('-c', '--centre', metavar='centre',
                        action='store', dest='centre',
                        default='[0.0, 0.0]', help=helps['centre'])
    parser.add_argument('-s', '--shape', metavar='shape',
                        action='store', dest='shape',
                        default='[11, 11]', help=helps['shape'])
    parser.add_argument('-b', '--bc-kind', metavar='kind',
                        action='store', dest='bc_kind',
                        choices=['free', 'cantilever', 'fixed'],
                        default='free', help=helps['bc_kind'])
    parser.add_argument('-a', '--axis', metavar='0, ..., dim, or -1',
                        type=int, action='store', dest='axis',
                        default=-1, help=helps['axis'])
    parser.add_argument('--young', metavar='float', type=float,
                        action='store', dest='young',
                        default=6.80e+10, help=helps['young'])
    parser.add_argument('--poisson', metavar='float', type=float,
                        action='store', dest='poisson',
                        default=0.36, help=helps['poisson'])
    parser.add_argument('--density', metavar='float', type=float,
                        action='store', dest='density',
                        default=2700.0, help=helps['density'])
    parser.add_argument('--order', metavar='int', type=int,
                        action='store', dest='order',
                        default=1, help=helps['order'])
    parser.add_argument('-n', '--n-eigs', metavar='int', type=int,
                        action='store', dest='n_eigs',
                        default=6, help=helps['n_eigs'])
    parser.add_argument('-i', '--ignore', metavar='int', type=int,
                        action='store', dest='ignore',
                        default=None, help=helps['ignore'])
    parser.add_argument('--solver', metavar='solver', action='store',
                        dest='solver',
                        default= \
                        "eig.scipy,method:'eigh',tol:1e-5,maxiter:1000",
                        help=helps['solver'])
    parser.add_argument('--show',
                        action="store_true", dest='show',
                        default=False, help=helps['show'])
    parser.add_argument('filename', nargs='?', default=None)
    options = parser.parse_args()

    aux = options.solver.split(',')
    kwargs = {}
    for option in aux[1:]:
        key, val = option.split(':')
        kwargs[key.strip()] = eval(val)
    eig_conf = Struct(name='evp', kind=aux[0], **kwargs)

    output('using values:')
    output("  Young's modulus:", options.young)
    output("  Poisson's ratio:", options.poisson)
    output('  density:', options.density)
    output('displacement field approximation order:', options.order)
    output('requested %d eigenvalues' % options.n_eigs)
    output('using eigenvalue problem solver:', eig_conf.kind)
    output.level += 1
    for key, val in six.iteritems(kwargs):
        output('%s: %r' % (key, val))
    output.level -= 1

    assert_((0.0 < options.poisson < 0.5),
            "Poisson's ratio must be in ]0, 0.5[!")
    assert_((0 < options.order),
            'displacement approximation order must be at least 1!')

    filename = options.filename
    if filename is not None:
        mesh = Mesh.from_file(filename)
        dim = mesh.dim
        dims = nm.diff(mesh.get_bounding_box(), axis=0)

    else:
        dims = nm.array(eval(options.dims), dtype=nm.float64)
        dim = len(dims)

        centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim]
        shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim]

        output('dimensions:', dims)
        output('centre:    ', centre)
        output('shape:     ', shape)

        mesh = gen_block_mesh(dims, shape, centre, name='mesh')

    output('axis:      ', options.axis)
    assert_((-dim <= options.axis < dim), 'invalid axis value!')

    eig_solver = Solver.any_from_conf(eig_conf)

    # Build the problem definition.
    domain = FEDomain('domain', mesh)

    bbox = domain.get_mesh_bounding_box()
    min_coor, max_coor = bbox[:, options.axis]
    eps = 1e-8 * (max_coor - min_coor)
    ax = 'xyz'[:dim][options.axis]

    omega = domain.create_region('Omega', 'all')
    bottom = domain.create_region('Bottom',
                                  'vertices in (%s < %.10f)'
                                  % (ax, min_coor + eps),
                                  'facet')
    bottom_top = domain.create_region('BottomTop',
                                      'r.Bottom +v vertices in (%s > %.10f)'
                                      % (ax, max_coor - eps),
                                      'facet')

    field = Field.from_args('fu', nm.float64, 'vector', omega,
                            approx_order=options.order)

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

    mtx_d = stiffness_from_youngpoisson(dim, options.young, options.poisson)

    m = Material('m', D=mtx_d, rho=options.density)

    integral = Integral('i', order=2*options.order)

    t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u)
    t2 = Term.new('dw_volume_dot(m.rho, v, u)', integral, omega, m=m, v=v, u=u)
    eq1 = Equation('stiffness', t1)
    eq2 = Equation('mass', t2)
    lhs_eqs = Equations([eq1, eq2])

    pb = Problem('modal', equations=lhs_eqs)

    if options.bc_kind == 'free':
        pb.time_update()
        n_rbm = dim * (dim + 1) / 2

    elif options.bc_kind == 'cantilever':
        fixed = EssentialBC('Fixed', bottom, {'u.all' : 0.0})
        pb.time_update(ebcs=Conditions([fixed]))
        n_rbm = 0

    elif options.bc_kind == 'fixed':
        fixed = EssentialBC('Fixed', bottom_top, {'u.all' : 0.0})
        pb.time_update(ebcs=Conditions([fixed]))
        n_rbm = 0

    else:
        raise ValueError('unsupported BC kind! (%s)' % options.bc_kind)

    if options.ignore is not None:
        n_rbm = options.ignore

    pb.update_materials()

    # Assemble stiffness and mass matrices.
    mtx_k = eq1.evaluate(mode='weak', dw_mode='matrix', asm_obj=pb.mtx_a)
    mtx_m = mtx_k.copy()
    mtx_m.data[:] = 0.0
    mtx_m = eq2.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m)

    try:
        eigs, svecs = eig_solver(mtx_k, mtx_m, options.n_eigs + n_rbm,
                                 eigenvectors=True)

    except sla.ArpackNoConvergence as ee:
        eigs = ee.eigenvalues
        svecs = ee.eigenvectors
        output('only %d eigenvalues converged!' % len(eigs))

    output('%d eigenvalues converged (%d ignored as rigid body modes)' %
           (len(eigs), n_rbm))

    eigs = eigs[n_rbm:]
    svecs = svecs[:, n_rbm:]

    omegas = nm.sqrt(eigs)
    freqs = omegas / (2 * nm.pi)

    output('number |         eigenvalue |  angular frequency '
           '|          frequency')
    for ii, eig in enumerate(eigs):
        output('%6d | %17.12e | %17.12e | %17.12e'
               % (ii + 1, eig, omegas[ii], freqs[ii]))

    # Make full eigenvectors (add DOFs fixed by boundary conditions).
    variables = pb.get_variables()

    vecs = nm.empty((variables.di.ptr[-1], svecs.shape[1]),
                    dtype=nm.float64)
    for ii in range(svecs.shape[1]):
        vecs[:, ii] = variables.make_full_vec(svecs[:, ii])

    # Save the eigenvectors.
    out = {}
    state = pb.create_state()
    for ii in range(eigs.shape[0]):
        state.set_full(vecs[:, ii])
        aux = state.create_output_dict()
        strain = pb.evaluate('ev_cauchy_strain.i.Omega(u)',
                             integrals=Integrals([integral]),
                             mode='el_avg', verbose=False)
        out['u%03d' % ii] = aux.popitem()[1]
        out['strain%03d' % ii] = Struct(mode='cell', data=strain)

    pb.save_state('eigenshapes.vtk', out=out)
    pb.save_regions_as_groups('regions')

    if len(eigs) and options.show:
        # Show the solution. If the approximation order is greater than 1, the
        # extra DOFs are simply thrown away.
        from sfepy.postprocess.viewer import Viewer
        from sfepy.postprocess.domain_specific import DomainSpecificPlot

        scaling = 0.05 * dims.max() / nm.abs(vecs).max()

        ds = {}
        for ii in range(eigs.shape[0]):
            pd = DomainSpecificPlot('plot_displacements',
                                    ['rel_scaling=%s' % scaling,
                                     'color_kind="tensors"',
                                     'color_name="strain%03d"' % ii])
            ds['u%03d' % ii] = pd

        view = Viewer('eigenshapes.vtk')
        view(domain_specific=ds, only_names=sorted(ds.keys()),
             is_scalar_bar=False, is_wireframe=True)
Beispiel #44
0
def save_basis_on_mesh(mesh,
                       options,
                       output_dir,
                       lin,
                       permutations=None,
                       suffix=''):
    if permutations is not None:
        mesh = mesh.copy()
        gel = GeometryElement(mesh.descs[0])
        perms = gel.get_conn_permutations()[permutations]
        conn = mesh.cmesh.get_cell_conn()
        n_el, n_ep = conn.num, gel.n_vertex
        offsets = nm.arange(n_el) * n_ep

        conn.indices[:] = conn.indices.take((perms + offsets[:, None]).ravel())

    domain = FEDomain('domain', mesh)

    omega = domain.create_region('Omega', 'all')
    field = Field.from_args('f',
                            nm.float64,
                            shape=1,
                            region=omega,
                            approx_order=options.max_order,
                            poly_space_base=options.basis)
    var = FieldVariable('u', 'unknown', field)

    if options.plot_dofs:
        import sfepy.postprocess.plot_dofs as pd
        import sfepy.postprocess.plot_cmesh as pc
        ax = pc.plot_wireframe(None, mesh.cmesh)
        ax = pd.plot_global_dofs(ax, field.get_coor(), field.econn)
        ax = pd.plot_local_dofs(ax, field.get_coor(), field.econn)
        if options.dofs is not None:
            ax = pd.plot_nodes(ax, field.get_coor(), field.econn,
                               field.poly_space.nodes,
                               get_dofs(options.dofs, var.n_dof))
        pd.plt.show()

    output('dofs: %d' % var.n_dof)

    vec = nm.empty(var.n_dof, dtype=var.dtype)
    n_digit, _format = get_print_info(var.n_dof, fill='0')
    name_template = os.path.join(output_dir,
                                 'dof_%s%s.vtk' % (_format, suffix))
    for ip in get_dofs(options.dofs, var.n_dof):
        output('dof %d...' % ip)

        vec.fill(0.0)
        vec[ip] = 1.0

        var.set_data(vec)

        if options.derivative == 0:
            out = var.create_output(vec, linearization=lin)

        else:
            out = create_expression_output('ev_grad.ie.Elements(u)',
                                           'u',
                                           'f', {'f': field},
                                           None,
                                           Variables([var]),
                                           mode='qp',
                                           verbose=False,
                                           min_level=lin.min_level,
                                           max_level=lin.max_level,
                                           eps=lin.eps)

        name = name_template % ip
        ensure_path(name)
        out['u'].mesh.write(name, out=out)

        output('...done (%s)' % name)
Beispiel #45
0
def main():
    parser = ArgumentParser(description=__doc__.rstrip(),
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('filename', help=helps['filename'])
    parser.add_argument('-d',
                        '--detailed',
                        action='store_true',
                        dest='detailed',
                        default=False,
                        help=helps['detailed'])
    options = parser.parse_args()

    mesh = Mesh.from_file(options.filename)

    output(mesh.cmesh)
    output('element types:', mesh.descs)
    output('nodal BCs:', sorted(mesh.nodal_bcs.keys()))

    bbox = mesh.get_bounding_box()
    output('bounding box:\n%s' %
           '\n'.join('%s: [%14.7e, %14.7e]' % (name, bbox[0, ii], bbox[1, ii])
                     for ii, name in enumerate('xyz'[:mesh.dim])))

    output('centre:           [%s]' %
           ', '.join('%14.7e' % ii for ii in 0.5 * (bbox[0] + bbox[1])))
    output('coordinates mean: [%s]' % ', '.join('%14.7e' % ii
                                                for ii in mesh.coors.mean(0)))

    if not options.detailed: return

    domain = FEDomain(mesh.name, mesh)

    for dim in range(1, mesh.cmesh.tdim + 1):
        volumes = mesh.cmesh.get_volumes(dim)
        output('volumes of %d %dD entities:\nmin: %.7e mean: %.7e median:'
               ' %.7e max: %.7e' %
               (mesh.cmesh.num[dim], dim, volumes.min(), volumes.mean(),
                nm.median(volumes), volumes.max()))

    euler = lambda mesh: nm.dot(mesh.cmesh.num, [1, -1, 1, -1])
    ec = euler(mesh)
    output('Euler characteristic:', ec)

    graph = mesh.create_conn_graph(verbose=False)
    n_comp, _ = graph_components(graph.shape[0], graph.indptr, graph.indices)
    output('number of connected components:', n_comp)

    if mesh.dim > 1:
        region = domain.create_region('surf', 'vertices of surface', 'facet')
        surf_mesh = Mesh.from_region(region,
                                     mesh,
                                     localize=True,
                                     is_surface=True)
        FEDomain(surf_mesh.name, surf_mesh)  # Calls CMesh.setup_entities().

        sec = euler(surf_mesh)
        output('surface Euler characteristic:', sec)
        if mesh.dim == 3:
            output('surface genus:', (2.0 - sec) / 2.0)

        surf_graph = surf_mesh.create_conn_graph(verbose=False)
        n_comp, _ = graph_components(surf_graph.shape[0], surf_graph.indptr,
                                     surf_graph.indices)
        output('number of connected surface components:', n_comp)
Beispiel #46
0
    def _solve(self, property_array):
        """
        Solve the Sfepy problem for one sample.

        Args:
          property_array: array of shape (n_x, n_y, 2) where the last
          index is for Lame's parameter and shear modulus,
          respectively.

        Returns:
          the strain field of shape (n_x, n_y, 2) where the last
          index represents the x and y displacements

        """
        shape = property_array.shape[:-1]
        mesh = self._get_mesh(shape)
        domain = Domain('domain', mesh)

        region_all = domain.create_region('region_all', 'all')

        field = Field.from_args(
            'fu',
            np.float64,
            'vector',
            region_all,  # pylint: disable=no-member
            approx_order=2)

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

        m = self._get_material(property_array, domain)

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

        t1 = Term.new('dw_lin_elastic_iso(m.lam, m.mu, v, u)',
                      integral,
                      region_all,
                      m=m,
                      v=v,
                      u=u)
        eq = Equation('balance_of_forces', t1)
        eqs = Equations([eq])

        epbcs, functions = self._get_periodicBCs(domain)
        ebcs = self._get_displacementBCs(domain)
        lcbcs = self._get_linear_combinationBCs(domain)

        ls = ScipyDirect({})

        pb = Problem('elasticity', equations=eqs, functions=functions)

        pb.time_update(ebcs=ebcs, epbcs=epbcs, lcbcs=lcbcs)

        ev = pb.get_evaluator()
        nls = Newton({},
                     lin_solver=ls,
                     fun=ev.eval_residual,
                     fun_grad=ev.eval_tangent_matrix)

        try:
            pb.set_solvers_instances(ls, nls)
        except AttributeError:
            pb.set_solver(nls)

        vec = pb.solve()

        u = vec.create_output_dict()['u'].data
        u_reshape = np.reshape(u, (tuple(x + 1 for x in shape) + u.shape[-1:]))

        dims = domain.get_mesh_bounding_box().shape[1]
        strain = np.squeeze(
            pb.evaluate(
                'ev_cauchy_strain.{dim}.region_all(u)'.format(dim=dims),
                mode='el_avg',
                copy_materials=False))
        strain_reshape = np.reshape(strain, (shape + strain.shape[-1:]))

        stress = np.squeeze(
            pb.evaluate(
                'ev_cauchy_stress.{dim}.region_all(m.D, u)'.format(dim=dims),
                mode='el_avg',
                copy_materials=False))
        stress_reshape = np.reshape(stress, (shape + stress.shape[-1:]))

        return strain_reshape, u_reshape, stress_reshape
Beispiel #47
0
def main():
    parser = OptionParser(usage=usage, version='%prog')
    parser.add_option('-d',
                      '--dims',
                      metavar='dims',
                      action='store',
                      dest='dims',
                      default='[1.0, 1.0]',
                      help=helps['dims'])
    parser.add_option('-c',
                      '--centre',
                      metavar='centre',
                      action='store',
                      dest='centre',
                      default='[0.0, 0.0]',
                      help=helps['centre'])
    parser.add_option('-s',
                      '--shape',
                      metavar='shape',
                      action='store',
                      dest='shape',
                      default='[11, 11]',
                      help=helps['shape'])
    parser.add_option('-b',
                      '--bc-kind',
                      metavar='kind',
                      action='store',
                      dest='bc_kind',
                      choices=['free', 'clamped'],
                      default='free',
                      help=helps['bc_kind'])
    parser.add_option('--young',
                      metavar='float',
                      type=float,
                      action='store',
                      dest='young',
                      default=6.80e+10,
                      help=helps['young'])
    parser.add_option('--poisson',
                      metavar='float',
                      type=float,
                      action='store',
                      dest='poisson',
                      default=0.36,
                      help=helps['poisson'])
    parser.add_option('--density',
                      metavar='float',
                      type=float,
                      action='store',
                      dest='density',
                      default=2700.0,
                      help=helps['density'])
    parser.add_option('--order',
                      metavar='int',
                      type=int,
                      action='store',
                      dest='order',
                      default=1,
                      help=helps['order'])
    parser.add_option('-n',
                      '--n-eigs',
                      metavar='int',
                      type=int,
                      action='store',
                      dest='n_eigs',
                      default=6,
                      help=helps['order'])
    parser.add_option('',
                      '--show',
                      action="store_true",
                      dest='show',
                      default=False,
                      help=helps['show'])
    options, args = parser.parse_args()

    assert_((0.0 < options.poisson < 0.5),
            "Poisson's ratio must be in ]0, 0.5[!")
    assert_((0 < options.order),
            'displacement approximation order must be at least 1!')

    dims = nm.array(eval(options.dims), dtype=nm.float64)
    dim = len(dims)
    centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim]
    shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim]

    output('dimensions:', dims)
    output('centre:    ', centre)
    output('shape:     ', shape)
    output('using values:')
    output("  Young's modulus:", options.young)
    output("  Poisson's ratio:", options.poisson)
    output('  density:', options.density)

    # Build the problem definition.
    mesh = gen_block_mesh(dims, shape, centre, name='mesh')
    domain = FEDomain('domain', mesh)

    bbox = domain.get_mesh_bounding_box()
    min_y, max_y = bbox[:, 1]
    eps = 1e-8 * (max_y - min_y)
    omega = domain.create_region('Omega', 'all')
    bottom = domain.create_region('Bottom',
                                  'vertices in (y < %.10f)' % (min_y + eps),
                                  'facet')

    field = Field.from_args('fu',
                            nm.float64,
                            'vector',
                            omega,
                            approx_order=options.order)

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

    mtx_d = stiffness_from_youngpoisson(dim, options.young, options.poisson)

    m = Material('m', D=mtx_d, rho=options.density)

    integral = Integral('i', order=2 * options.order)

    t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u)
    t2 = Term.new('dw_volume_dot(m.rho, v, u)', integral, omega, m=m, v=v, u=u)
    eq1 = Equation('stiffness', t1)
    eq2 = Equation('mass', t2)
    lhs_eqs = Equations([eq1, eq2])

    pb = Problem('modal', equations=lhs_eqs)

    if options.bc_kind == 'free':
        pb.time_update()
        n_rbm = dim * (dim + 1) / 2

    else:
        fixed_b = EssentialBC('FixedB', bottom, {'u.all': 0.0})
        pb.time_update(ebcs=Conditions([fixed_b]))
        n_rbm = 0

    pb.update_materials()

    # Assemble stiffness and mass matrices.
    mtx_k = eq1.evaluate(mode='weak', dw_mode='matrix', asm_obj=pb.mtx_a)
    mtx_m = mtx_k.copy()
    mtx_m.data[:] = 0.0
    mtx_m = eq2.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m)

    try:
        eigs, svecs = sla.eigsh(mtx_k,
                                k=options.n_eigs + n_rbm,
                                M=mtx_m,
                                which='SM',
                                tol=1e-5,
                                maxiter=10000)
    except sla.ArpackNoConvergence as ee:
        eigs = ee.eigenvalues
        svecs = ee.eigenvectors
        output('only %d eigenvalues converged!' % len(eigs))

    eigs = eigs[n_rbm:]
    svecs = svecs[:, n_rbm:]

    output('eigenvalues:', eigs)
    output('eigen-frequencies:', nm.sqrt(eigs))

    # Make full eigenvectors (add DOFs fixed by boundary conditions).
    variables = pb.get_variables()

    vecs = nm.empty((variables.di.ptr[-1], svecs.shape[1]), dtype=nm.float64)
    for ii in xrange(svecs.shape[1]):
        vecs[:, ii] = variables.make_full_vec(svecs[:, ii])

    # Save the eigenvectors.
    out = {}
    state = pb.create_state()
    for ii in xrange(eigs.shape[0]):
        state.set_full(vecs[:, ii])
        aux = state.create_output_dict()
        strain = pb.evaluate('ev_cauchy_strain.i.Omega(u)',
                             integrals=Integrals([integral]),
                             mode='el_avg',
                             verbose=False)
        out['u%03d' % ii] = aux.popitem()[1]
        out['strain%03d' % ii] = Struct(mode='cell', data=strain)

    pb.save_state('eigenshapes.vtk', out=out)
    pb.save_regions_as_groups('regions')

    if options.show:
        # Show the solution. If the approximation order is greater than 1, the
        # extra DOFs are simply thrown away.
        from sfepy.postprocess.viewer import Viewer
        from sfepy.postprocess.domain_specific import DomainSpecificPlot

        scaling = 0.05 * dims.max() / nm.abs(vecs).max()

        ds = {}
        for ii in xrange(eigs.shape[0]):
            pd = DomainSpecificPlot('plot_displacements', [
                'rel_scaling=%s' % scaling, 'color_kind="tensors"',
                'color_name="strain%03d"' % ii
            ])
            ds['u%03d' % ii] = pd

        view = Viewer('eigenshapes.vtk')
        view(domain_specific=ds,
             only_names=sorted(ds.keys()),
             is_scalar_bar=False,
             is_wireframe=True)
Beispiel #48
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()
    options_probe = True


    folder = str(uuid.uuid4())
    os.mkdir(folder)
    os.chdir(folder)

    file = open('README.txt', 'w')
    file.write('DIMENSIONS\n')
    file.write('Lx = '+str(dims[0])+' Ly = '+str(dims[1])+' Lz = '+str(dims[2])+'\n')
    file.write('DISCRETIZATION (NX, NY, NZ)\n')
    file.write(str(NX)+'  '+str(NY)+'  '+str(NZ)+'\n')
    file.write('MATERIALS\n')
    file.write(str(E_f)+' '+str(nu_f)+' '+str(E_m)+' '+str(nu_m)+'\n')

    #mesh = Mesh.from_file(data_dir + '/meshes/2d/rectangle_tri.mesh')

    mesh = mesh_generators.gen_block_mesh(dims,shape,centre,name='block')
    domain = FEDomain('domain', mesh)

    min_x, max_x = domain.get_mesh_bounding_box()[:,0]
    min_y, max_y = domain.get_mesh_bounding_box()[:,1]
    min_z, max_z = domain.get_mesh_bounding_box()[:,2]
    eps = 1e-8 * (max_x - min_x)
    print min_x, max_x
    print min_y, max_y
    print min_z, max_z
    R1 = domain.create_region('Ym',
                                  'vertices in z < %.10f' % (max_z/2))
    R2 = domain.create_region('Yf',
                                  'vertices in z >= %.10f' % (min_z/2))
    omega = domain.create_region('Omega', 'all')
    gamma1 = domain.create_region('Left',
                                  'vertices in x < %.10f' % (min_x + eps),
                                  'facet')
    gamma2 = domain.create_region('Right',
                                  'vertices in x > %.10f' % (max_x - eps),
                                  'facet')
    gamma3 = domain.create_region('Front',
                                  'vertices in y < %.10f' % (min_y + eps),
                                  'facet')
    gamma4 = domain.create_region('Back',
                                  'vertices in y > %.10f' % (max_y - eps),
                                  'facet')
    gamma5 = domain.create_region('Bottom',
                                  'vertices in z < %.10f' % (min_z + eps),
                                  'facet')
    gamma6 = domain.create_region('Top',
                                  'vertices in z > %.10f' % (max_z - eps),
                                  'facet')



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

    u = FieldVariable('u', 'unknown', field)
    v = FieldVariable('v', 'test', field, primary_var_name='u')
    mu=1.1
    lam=1.0
    m = Material('m', lam=lam, mu=mu)
    f = Material('f', val=[[0.0], [0.0],[-1.0]])
    load = Material('Load',val=[[0.0],[0.0],[-Load]])

    D = stiffness_from_lame(3,lam, mu)
    mat = Material('Mat', D=D)

    get_mat = Function('get_mat1',get_mat1)
    get_mat_f = Function('get_mat_f',get_mat1)

    integral = Integral('i', order=3)
    s_integral = Integral('is',order=2)

    t1 = Term.new('dw_lin_elastic(Mat.D, v, u)',
         integral, omega, Mat=mat, v=v, u=u)
    t2 = Term.new('dw_volume_lvf(f.val, v)', integral, omega, f=f, v=v)
    #t3 = Term.new('DotProductSurfaceTerm(Load.val, v)',s_integral,gamma5,Load=load,v=v)
    t3 = Term.new('dw_surface_ltr( Load.val, v )',s_integral,gamma6,Load=load,v=v)
    eq = Equation('balance', t1 + t2 + t3)
    eqs = Equations([eq])

    fix_u = EssentialBC('fix_u', gamma1, {'u.all' : 0.0})
    left_bc  = EssentialBC('Left',  gamma1, {'u.0' : 0.0})
    right_bc = EssentialBC('Right', gamma2, {'u.0' : 0.0})
    back_bc = EssentialBC('Front', gamma3, {'u.1' : 0.0})
    front_bc = EssentialBC('Back', gamma4, {'u.1' : 0.0})
    bottom_bc = EssentialBC('Bottom', gamma5, {'u.all' : 0.0})
    top_bc = EssentialBC('Top', gamma6, {'u.2' : 0.2})

    bc=[left_bc,right_bc,back_bc,front_bc,bottom_bc]
    #bc=[bottom_bc,top_bc]


    ##############################
    #  ##### SOLVER SECTION  #####
    ##############################

    conf = Struct(method='bcgsl', precond='jacobi', sub_precond=None,
                  i_max=10000, eps_a=1e-50, eps_r=1e-10, eps_d=1e4,
                  verbose=True)

    ls = PETScKrylovSolver(conf)

    file.write(str(ls.name)+' '+str(ls.conf.method)+' '+str(ls.conf.precond)+' '+str(ls.conf.eps_r)+' '+str(ls.conf.i_max)+'\n' )

    nls_status = IndexedStruct()
    nls = Newton({'i_max':1,'eps_a':1e-10}, lin_solver=ls, status=nls_status)

    pb = Problem('elasticity', equations=eqs, nls=nls, ls=ls)

    dd=pb.get_materials()['Mat']
    dd.set_function(get_mat1)
    #xload = pb.get_materials()['f']
    #xload.set_function(get_mat_f)

    pb.save_regions_as_groups('regions')

    pb.time_update(ebcs=Conditions(bc))

    vec = pb.solve()
    print nls_status


    file.write('TIME TO SOLVE\n')
    file.write(str(nls.status.time_stats['solve'])+'\n')
    file.write('TIME TO CREATE MATRIX\n')
    file.write(str(nls.status.time_stats['matrix'])+'\n')

    ev = pb.evaluate
    out = vec.create_output_dict()
    strain = ev('ev_cauchy_strain.3.Omega(u)', mode='el_avg')
    stress = ev('ev_cauchy_stress.3.Omega(Mat.D, u)', mode='el_avg',
                copy_materials=False)

    out['cauchy_strain'] = Struct(name='output_data', mode='cell',
                                  data=strain, dofs=None)
    out['cauchy_stress'] = Struct(name='output_data', mode='cell',
                                  data=stress, dofs=None)

    pb.save_state('strain.vtk', out=out)

    print nls_status


    file.close()
Beispiel #49
0
    def from_conf(conf, options):
        from sfepy.discrete import FieldVariable, Variables, Problem
        from sfepy.discrete.fem import Mesh, FEDomain, Field

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

        omega = domain.create_region('Omega', 'all')
        domain.create_region('Left',
                             'vertices in (x < -0.499)',
                             'facet')
        domain.create_region('LeftStrip',
                             'vertices in (x < -0.499)'
                             ' & (y > -0.199) & (y < 0.199)',
                             'facet')
        domain.create_region('LeftFix',
                             'r.Left -v r.LeftStrip',
                             'facet')
        domain.create_region('Right',
                             'vertices in (x > 0.499)',
                             'facet')
        domain.create_region('RightStrip',
                             'vertices in (x > 0.499)'
                             ' & (y > -0.199) & (y < 0.199)',
                             'facet')
        domain.create_region('RightFix',
                             'r.Right -v r.RightStrip',
                             'facet')

        fu = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=2)
        u = FieldVariable('u', 'unknown', fu)

        fp = Field.from_args('fp', nm.float64, 'scalar', omega, approx_order=2)
        p = FieldVariable('p', 'unknown', fp)

        pb = Problem('test', domain=domain, fields=[fu, fp],
                     auto_conf=False, auto_solvers=False)

        test = Test(problem=pb, variables=Variables([u, p]),
                    conf=conf, options=options)
        return test
def main():
    from sfepy import data_dir

    parser = ArgumentParser()
    parser.add_argument('--version', action='version', version='%(prog)s')
    parser.add_argument('-s',
                        '--show',
                        action="store_true",
                        dest='show',
                        default=False,
                        help=helps['show'])
    options = parser.parse_args()

    mesh = Mesh.from_file(data_dir + '/meshes/2d/rectangle_tri.mesh')
    domain = FEDomain('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',
                                  'vertices in x < %.10f' % (min_x + eps),
                                  'facet')
    gamma2 = domain.create_region('Gamma2',
                                  'vertices in x > %.10f' % (max_x - eps),
                                  'facet')

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

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

    m = Material('m', D=stiffness_from_lame(dim=2, 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(m.D, 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 = Problem('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)
Beispiel #51
0
    def test_linearization(self):
        from sfepy.base.base import Struct
        from sfepy.discrete.fem import Mesh, FEDomain, Field
        from sfepy import data_dir

        geometries = ['2_3', '2_4', '3_4', '3_8']
        approx_orders = [1, 2]
        funs = [nm.cos, nm.sin, lambda x: x]

        ok = True
        for geometry in geometries:
            name = os.path.join(data_dir,
                                'meshes/elements/%s_1.mesh' % geometry)
            mesh = Mesh.from_file(name)

            domain = FEDomain('', mesh)
            domain = domain.refine()

            domain.mesh.write(self.join('linearizer-%s-0.mesh' % geometry))

            omega = domain.create_region('Omega', 'all')

            for approx_order in approx_orders:
                for dpn in [1, mesh.dim]:
                    self.report('geometry: %s, approx. order: %d, dpn: %d' %
                                (geometry, approx_order, dpn))

                    field = Field.from_args('fu', nm.float64, dpn, omega,
                                            approx_order=approx_order)

                    cc = field.get_coor()
                    dofs = nm.zeros((field.n_nod, dpn), dtype=nm.float64)

                    for ic in range(dpn):
                        dofs[:, ic] = funs[ic](3 * (cc[:, 0] * cc[:, 1]))

                    vmesh, vdofs, level = field.linearize(dofs,
                                                          min_level=0,
                                                          max_level=3,
                                                          eps=1e-2)

                    if approx_order == 1:
                        _ok = level == 0

                    else:
                        _ok = level > 0
                    self.report('max. refinement level: %d: %s' % (level, _ok))

                    ok = ok and _ok

                    rdofs = nm.zeros((vmesh.n_nod, dpn), dtype=nm.float64)
                    cc = vmesh.coors
                    for ic in range(dpn):
                        rdofs[:, ic] = funs[ic](3 * (cc[:, 0] * cc[:, 1]))

                    _ok = nm.allclose(rdofs, vdofs, rtol=0.0, atol=0.03)
                    self.report('interpolation: %s' % _ok)
                    ok = ok and _ok

                    out = {
                        'u' : Struct(name='output_data',
                                     mode='vertex', data=vdofs,
                                     var_name='u', dofs=None)
                    }

                    name = self.join('linearizer-%s-%d-%d'
                                     % (geometry, approx_order, dpn))

                    vmesh.write(name + '.mesh')
                    vmesh.write(name + '.vtk', out=out)

        return ok
def create_local_problem(omega_gi, orders):
    """
    Local problem definition using a domain corresponding to the global region
    `omega_gi`.
    """
    order_u, order_p = orders

    mesh = omega_gi.domain.mesh

    # All tasks have the whole mesh.
    bbox = mesh.get_bounding_box()
    min_x, max_x = bbox[:, 0]
    eps_x = 1e-8 * (max_x - min_x)

    min_y, max_y = bbox[:, 1]
    eps_y = 1e-8 * (max_y - min_y)

    mesh_i = Mesh.from_region(omega_gi, mesh, localize=True)
    domain_i = FEDomain('domain_i', mesh_i)
    omega_i = domain_i.create_region('Omega', 'all')

    gamma1_i = domain_i.create_region('Gamma1',
                                      'vertices in (x < %.10f)' %
                                      (min_x + eps_x),
                                      'facet',
                                      allow_empty=True)
    gamma2_i = domain_i.create_region('Gamma2',
                                      'vertices in (x > %.10f)' %
                                      (max_x - eps_x),
                                      'facet',
                                      allow_empty=True)
    gamma3_i = domain_i.create_region('Gamma3',
                                      'vertices in (y < %.10f)' %
                                      (min_y + eps_y),
                                      'facet',
                                      allow_empty=True)

    field1_i = Field.from_args('fu',
                               nm.float64,
                               mesh.dim,
                               omega_i,
                               approx_order=order_u)

    field2_i = Field.from_args('fp',
                               nm.float64,
                               1,
                               omega_i,
                               approx_order=order_p)

    output('field 1: number of local DOFs:', field1_i.n_nod)
    output('field 2: number of local DOFs:', field2_i.n_nod)

    u_i = FieldVariable('u_i', 'unknown', field1_i, order=0)
    v_i = FieldVariable('v_i', 'test', field1_i, primary_var_name='u_i')
    p_i = FieldVariable('p_i', 'unknown', field2_i, order=1)
    q_i = FieldVariable('q_i', 'test', field2_i, primary_var_name='p_i')

    if mesh.dim == 2:
        alpha = 1e2 * nm.array([[0.132], [0.132], [0.092]])

    else:
        alpha = 1e2 * nm.array([[0.132], [0.132], [0.132], [0.092], [0.092],
                                [0.092]])

    mat = Material('m',
                   D=stiffness_from_lame(mesh.dim, lam=10, mu=5),
                   k=1,
                   alpha=alpha)
    integral = Integral('i', order=2 * (max(order_u, order_p)))

    t11 = Term.new('dw_lin_elastic(m.D, v_i, u_i)',
                   integral,
                   omega_i,
                   m=mat,
                   v_i=v_i,
                   u_i=u_i)
    t12 = Term.new('dw_biot(m.alpha, v_i, p_i)',
                   integral,
                   omega_i,
                   m=mat,
                   v_i=v_i,
                   p_i=p_i)
    t21 = Term.new('dw_biot(m.alpha, u_i, q_i)',
                   integral,
                   omega_i,
                   m=mat,
                   u_i=u_i,
                   q_i=q_i)
    t22 = Term.new('dw_laplace(m.k, q_i, p_i)',
                   integral,
                   omega_i,
                   m=mat,
                   q_i=q_i,
                   p_i=p_i)

    eq1 = Equation('eq1', t11 - t12)
    eq2 = Equation('eq1', t21 + t22)
    eqs = Equations([eq1, eq2])

    ebc1 = EssentialBC('ebc1', gamma1_i, {'u_i.all': 0.0})
    ebc2 = EssentialBC('ebc2', gamma2_i, {'u_i.0': 0.05})

    def bc_fun(ts, coors, **kwargs):
        val = 0.3 * nm.sin(4 * nm.pi * (coors[:, 0] - min_x) / (max_x - min_x))
        return val

    fun = Function('bc_fun', bc_fun)
    ebc3 = EssentialBC('ebc3', gamma3_i, {'p_i.all': fun})

    pb = Problem('problem_i', equations=eqs, active_only=False)
    pb.time_update(ebcs=Conditions([ebc1, ebc2, ebc3]))
    pb.update_materials()

    return pb