Beispiel #1
0
    def test_volume_tl(self):
        from sfepy.discrete import FieldVariable

        fu = self.problem.fields['vector']
        fq = self.problem.fields['scalar']

        var_u = FieldVariable('u',
                              'parameter',
                              fu,
                              primary_var_name='(set-to-None)')
        var_q = FieldVariable('q',
                              'test',
                              fq,
                              primary_var_name='(set-to-None)')

        var_u.set_data(nm.linspace(0, 0.004, var_u.n_dof))

        vval = self.problem.evaluate('dw_tl_volume.i.Omega( q, u )',
                                     term_mode='volume',
                                     q=var_q,
                                     u=var_u)

        sval = self.problem.evaluate('d_tl_volume_surface.i.Gamma( u )',
                                     u=var_u)

        ok = abs(vval - sval) < 1e-14

        self.report('TL: by volume: %e == by surface: %e -> %s' %
                    (vval, sval, ok))

        return ok
Beispiel #2
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
    def test_surface_evaluate(self):
        from sfepy.discrete import FieldVariable
        problem = self.problem

        us = problem.get_variables()['us']
        vec = nm.empty(us.n_dof, dtype=us.dtype)
        vec[:] = 1.0
        us.set_data(vec)

        expr = 'ev_surface_integrate.i.Left( us )'
        val = problem.evaluate(expr, us=us)
        ok1 = nm.abs(val - 1.0) < 1e-15
        self.report('with unknown: %s, value: %s, ok: %s' % (expr, val, ok1))

        ps1 = FieldVariable('ps1',
                            'parameter',
                            us.get_field(),
                            primary_var_name='(set-to-None)')
        ps1.set_data(vec)

        expr = 'ev_surface_integrate.i.Left( ps1 )'
        val = problem.evaluate(expr, ps1=ps1)
        ok2 = nm.abs(val - 1.0) < 1e-15
        self.report('with parameter: %s, value: %s, ok: %s' % (expr, val, ok2))
        ok2 = True

        return ok1 and ok2
def nodal_stress(out, pb, state, extend=False, integrals=None):
    '''
    Calculate stresses at nodal points.
    '''

    # Point load.
    mat = pb.get_materials()['Load']
    P = 2.0 * mat.get_data('special', 'val')[1]

    # Calculate nodal stress.
    pb.time_update()

    if integrals is None: integrals = pb.get_integrals()

    stress = pb.evaluate('ev_cauchy_stress.ivn.Omega(Asphalt.D, u)', mode='qp',
                         integrals=integrals, copy_materials=False)
    sfield = Field.from_args('stress', nm.float64, (3,),
                             pb.domain.regions['Omega'])
    svar = FieldVariable('sigma', 'parameter', sfield,
                         primary_var_name='(set-to-None)')
    svar.set_from_qp(stress, integrals['ivn'])

    print('\n==================================================================')
    print('Given load = %.2f N' % -P)
    print('\nAnalytical solution')
    print('===================')
    print('Horizontal tensile stress = %.5e MPa/mm' % (-2.*P/(nm.pi*150.)))
    print('Vertical compressive stress = %.5e MPa/mm' % (-6.*P/(nm.pi*150.)))
    print('\nFEM solution')
    print('============')
    print('Horizontal tensile stress = %.5e MPa/mm' % (svar()[0]))
    print('Vertical compressive stress = %.5e MPa/mm' % (-svar()[1]))
    print('==================================================================') 
    return out
Beispiel #5
0
def verify_save_dof_maps(field, cell_tasks, dof_maps, id_map, options,
                         verbose=False):
    vec = pl.verify_task_dof_maps(dof_maps, id_map, field, verbose=verbose)

    order = options.order
    mesh = field.domain.mesh

    sfield = Field.from_args('aux', nm.float64, 'scalar', field.region,
                             approx_order=order)
    aux = FieldVariable('aux', 'parameter', sfield,
                        primary_var_name='(set-to-None)')
    out = aux.create_output(vec,
                            linearization=Struct(kind='adaptive',
                                                 min_level=order-1,
                                                 max_level=order-1,
                                                 eps=1e-8))

    filename = os.path.join(options.output_dir,
                            'para-domains-dofs.h5')
    if field.is_higher_order():
        out['aux'].mesh.write(filename, out=out)

    else:
        mesh.write(filename, out=out)

    out = Struct(name='cells', mode='cell',
                 data=cell_tasks[:, None, None, None])
    filename = os.path.join(options.output_dir,
                            'para-domains-cells.h5')
    mesh.write(filename, out={'cells' : out})
Beispiel #6
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 #7
0
    def test_surface_evaluate(self):
        from sfepy.discrete import FieldVariable
        problem = self.problem

        us = problem.get_variables()['us']
        vec = nm.empty(us.n_dof, dtype=us.dtype)
        vec[:] = 1.0
        us.set_data(vec)

        expr = 'ev_surface_integrate.i.Left( us )'
        val = problem.evaluate(expr, us=us)
        ok1 = nm.abs(val - 1.0) < 1e-15
        self.report('with unknown: %s, value: %s, ok: %s'
                    % (expr, val, ok1))

        ps1 = FieldVariable('ps1', 'parameter', us.get_field(),
                            primary_var_name='(set-to-None)')
        ps1.set_data(vec)

        expr = 'ev_surface_integrate.i.Left( ps1 )'
        val = problem.evaluate(expr, ps1=ps1)
        ok2 = nm.abs(val - 1.0) < 1e-15
        self.report('with parameter: %s, value: %s, ok: %s'
                    % (expr, val, ok2))
        ok2 = True

        return ok1 and ok2
Beispiel #8
0
def nodal_stress(out, pb, state, extend=False, integrals=None):
    """
    Calculate stresses at nodal points.
    """

    # Point load.
    mat = pb.get_materials()["Load"]
    P = 2.0 * mat.get_data("special", "val")[1]

    # Calculate nodal stress.
    pb.time_update()

    if integrals is None:
        integrals = pb.get_integrals()

    stress = pb.evaluate("ev_cauchy_stress.ivn.Omega(Asphalt.D, u)", mode="qp", integrals=integrals)
    sfield = Field.from_args("stress", nm.float64, (3,), pb.domain.regions["Omega"])
    svar = FieldVariable("sigma", "parameter", sfield, primary_var_name="(set-to-None)")
    svar.set_data_from_qp(stress, integrals["ivn"])

    print "\n=================================================================="
    print "Given load = %.2f N" % -P
    print "\nAnalytical solution"
    print "==================="
    print "Horizontal tensile stress = %.5e MPa/mm" % (-2.0 * P / (nm.pi * 150.0))
    print "Vertical compressive stress = %.5e MPa/mm" % (-6.0 * P / (nm.pi * 150.0))
    print "\nFEM solution"
    print "============"
    print "Horizontal tensile stress = %.5e MPa/mm" % (svar()[0][0])
    print "Vertical compressive stress = %.5e MPa/mm" % (-svar()[0][1])
    print "=================================================================="
    return out
Beispiel #9
0
    def test_volume_tl(self):
        from sfepy.discrete import FieldVariable

        fu = self.problem.fields['vector']
        fq = self.problem.fields['scalar']

        var_u = FieldVariable('u', 'parameter', fu,
                              primary_var_name='(set-to-None)')
        var_q = FieldVariable('q', 'test', fq,
                              primary_var_name='(set-to-None)')

        var_u.set_data(nm.linspace(0, 0.004, var_u.n_dof))

        vval = self.problem.evaluate('dw_tl_volume.i.Omega( q, u )',
                                     term_mode='volume', q=var_q, u=var_u)

        sval = self.problem.evaluate('d_tl_volume_surface.i.Gamma( u )',
                                     u=var_u)

        ok = abs(vval - sval) < 1e-14

        self.report('TL: by volume: %e == by surface: %e -> %s' %
                    (vval, sval, ok))

        return ok
Beispiel #10
0
def nodal_stress(out, pb, state, extend=False, integrals=None):
    '''
    Calculate stresses at nodal points.
    '''

    # Point load.
    mat = pb.get_materials()['Load']
    P = 2.0 * mat.get_data('special', 'val')[1]

    # Calculate nodal stress.
    pb.time_update()

    if integrals is None: integrals = pb.get_integrals()

    stress = pb.evaluate('ev_cauchy_stress.ivn.Omega(Asphalt.D, u)', mode='qp',
                         integrals=integrals, copy_materials=False)
    sfield = Field.from_args('stress', nm.float64, (3,),
                             pb.domain.regions['Omega'])
    svar = FieldVariable('sigma', 'parameter', sfield,
                         primary_var_name='(set-to-None)')
    svar.set_from_qp(stress, integrals['ivn'])

    print('\n==================================================================')
    print('Given load = %.2f N' % -P)
    print('\nAnalytical solution')
    print('===================')
    print('Horizontal tensile stress = %.5e MPa/mm' % (-2.*P/(nm.pi*150.)))
    print('Vertical compressive stress = %.5e MPa/mm' % (-6.*P/(nm.pi*150.)))
    print('\nFEM solution')
    print('============')
    print('Horizontal tensile stress = %.5e MPa/mm' % (svar()[0]))
    print('Vertical compressive stress = %.5e MPa/mm' % (-svar()[1]))
    print('==================================================================')
    return out
Beispiel #11
0
def solveLaplaceEquationTetrahedral(mesh, meshVTK, boundaryPoints,
                                    boundaryConditions):
    """
    mesh: path to a 3D mesh / sfepy mesh
    
    """
    if isinstance(mesh, str):
        mesh = Mesh.from_file(mesh)

    #Set domains
    domain = FEDomain('domain', mesh)
    omega = domain.create_region('Omega', 'all')
    boundary = domain.create_region(
        'gamma',
        'vertex  %s' % ','.join(map(str, range(meshVTK.GetNumberOfPoints()))),
        'facet')

    #set fields
    field = Field.from_args('fu', np.float64, 1, omega, approx_order=1)
    u = FieldVariable('u', 'unknown', field)
    v = FieldVariable('v', 'test', field, primary_var_name='u')
    m = Material('m', val=[1.])

    #Define element integrals
    integral = Integral('i', order=3)

    #Equations defining
    t1 = Term.new('dw_laplace( v, u )', integral, omega, v=v, u=u)
    eq = Equation('balance', t1)
    eqs = Equations([eq])

    heatBoundary = boundaryConditions
    points = boundaryPoints

    #Boundary conditions
    c = ClosestPointStupid(points, heatBoundary, meshVTK)

    def u_fun(ts, coors, bc=None, problem=None, c=c):
        c.distances = []
        v = np.zeros(len(coors))
        for i, p in enumerate(coors):
            v[i] = c.interpolate(p)
            #c.findClosestPoint(p)
        return v

    bc_fun = Function('u_fun', u_fun)
    fix1 = EssentialBC('fix_u', boundary, {'u.all': bc_fun})

    #Solve problem
    ls = ScipyDirect({})
    nls = Newton({}, lin_solver=ls)

    pb = Problem('heat', equations=eqs)
    pb.set_bcs(ebcs=Conditions([fix1]))

    pb.set_solver(nls)
    state = pb.solve(verbose=False, save_results=False)
    u = state.get_parts()['u']
    return u
Beispiel #12
0
    def test_solving(self):
        from sfepy.base.base import IndexedStruct
        from sfepy.discrete import (FieldVariable, Material, Problem, Function,
                                    Equation, Equations, Integral)
        from sfepy.discrete.conditions import Conditions, EssentialBC
        from sfepy.terms import Term
        from sfepy.solvers.ls import ScipyDirect
        from sfepy.solvers.nls import Newton
        from sfepy.mechanics.matcoefs import stiffness_from_lame

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

        m = Material('m', D=stiffness_from_lame(self.dim, 1.0, 1.0))
        f = Material('f', val=[[0.02], [0.01]])

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

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

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

        t1 = Term.new('dw_lin_elastic(m.D, v, u)',
                      integral, self.omega, m=m, v=v, u=u)

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

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

        ls = ScipyDirect({})

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

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

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

        state = pb.solve()

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

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

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

        ok = ok and _ok

        return ok
Beispiel #13
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 #14
0
def run(domain, order):
    omega = domain.create_region('Omega', 'all')
    bbox = domain.get_mesh_bounding_box()
    min_x, max_x = bbox[:, 0]
    min_y, max_y = bbox[:, 1]
    eps = 1e-8 * (max_x - min_x)
    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')
    gamma3 = domain.create_region('Gamma3',
                                  'vertices in y < %.10f' % (min_y + eps),
                                  'facet')
    gamma4 = domain.create_region('Gamma4',
                                  'vertices in y > %.10f' % (max_y - eps),
                                  'facet')

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

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

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

    t1 = Term.new('dw_laplace(v, u)', integral, omega, v=v, u=u)
    eq = Equation('eq', t1)
    eqs = Equations([eq])

    fix1 = EssentialBC('fix1', gamma1, {'u.0': 0.4})
    fix2 = EssentialBC('fix2', gamma2, {'u.0': 0.0})

    def get_shift(ts, coors, region):
        return nm.ones_like(coors[:, 0])

    dof_map_fun = Function('dof_map_fun', per.match_x_line)
    shift_fun = Function('shift_fun', get_shift)

    sper = LinearCombinationBC('sper', [gamma3, gamma4], {'u.0': 'u.0'},
                               dof_map_fun,
                               'shifted_periodic',
                               arguments=(shift_fun, ))

    ls = ScipyDirect({})
    nls = Newton({}, lin_solver=ls)

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

    pb.set_bcs(ebcs=Conditions([fix1, fix2]), lcbcs=Conditions([sper]))

    pb.set_solver(nls)

    state = pb.solve()

    return pb, state
def solve_problem(shape, dims, young, poisson, force, transform=None):
    domain = make_domain(dims[:2], shape, transform=transform)

    omega = domain.regions['Omega']
    gamma1 = domain.regions['Gamma1']
    gamma2 = domain.regions['Gamma2']

    field = Field.from_args('fu', nm.float64, 6, omega, approx_order=1,
                            poly_space_base='shell10x')
    u = FieldVariable('u', 'unknown', field)
    v = FieldVariable('v', 'test', field, primary_var_name='u')

    thickness = dims[2]
    if transform is None:
        pload = [[0.0, 0.0, force / shape[1], 0.0, 0.0, 0.0]] * shape[1]

    elif transform == 'bend':
        pload = [[force / shape[1], 0.0, 0.0, 0.0, 0.0, 0.0]] * shape[1]

    elif transform == 'twist':
        pload = [[0.0, force / shape[1], 0.0, 0.0, 0.0, 0.0]] * shape[1]

    m = Material('m', D=sh.create_elastic_tensor(young=young, poisson=poisson),
                 values={'.drill' : 1e-7})
    load = Material('load', values={'.val' : pload})

    aux = Integral('i', order=3)
    qp_coors, qp_weights = aux.get_qp('3_8')
    qp_coors[:, 2] = thickness * (qp_coors[:, 2] - 0.5)
    qp_weights *= thickness

    integral = Integral('i', coors=qp_coors, weights=qp_weights, order='custom')

    t1 = Term.new('dw_shell10x(m.D, m.drill, v, u)',
                  integral, omega, m=m, v=v, u=u)
    t2 = Term.new('dw_point_load(load.val, v)',
                  integral, gamma2, load=load, v=v)
    eq = Equation('balance', t1 - t2)
    eqs = Equations([eq])

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

    ls = ScipyDirect({})

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

    pb = Problem('elasticity with shell10x', equations=eqs, nls=nls, ls=ls)
    pb.time_update(ebcs=Conditions([fix_u]))

    state = pb.solve()

    return pb, state, u, gamma2
Beispiel #16
0
    def test_project_tensors(self):
        from sfepy.discrete import FieldVariable
        from sfepy.discrete.projections import project_by_component

        ok = True

        u = FieldVariable('u',
                          'parameter',
                          self.field,
                          primary_var_name='(set-to-None)')
        u.set_constant(1.0)

        component = FieldVariable('component',
                                  'parameter',
                                  self.field,
                                  primary_var_name='(set-to-None)')

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

        u_qp = u.evaluate()
        u2 = FieldVariable('u2',
                           'parameter',
                           self.field,
                           primary_var_name='(set-to-None)')
        project_by_component(u2,
                             u_qp,
                             component,
                             self.field.approx_order,
                             nls_options=nls_options)

        _ok = self.compare_vectors(u(), u2())
        ok = ok and _ok

        gu_qp = u.evaluate(mode='grad')

        gfield = Field.from_args('gu',
                                 nm.float64,
                                 2,
                                 self.field.region,
                                 approx_order=self.field.approx_order)
        gu = FieldVariable('gu',
                           'parameter',
                           gfield,
                           primary_var_name='(set-to-None)')

        project_by_component(gu,
                             gu_qp,
                             component,
                             gfield.approx_order,
                             nls_options=nls_options)

        _ok = self.compare_vectors(gu(), nm.zeros_like(gu()))
        ok = ok and _ok

        return ok
Beispiel #17
0
    def test_variables(self):
        from sfepy.discrete import FieldVariable, Integral

        ok = True

        u = FieldVariable('u',
                          'parameter',
                          self.field,
                          primary_var_name='(set-to-None)')
        u.set_constant(1.0)
        vec = u()  # Nodal values.

        _ok = nm.allclose(vec, 1.0)
        self.report('set constant:', _ok)
        ok = _ok and ok

        def fun(coors):
            val = nm.empty_like(coors)
            val[:, 0] = 2 * coors[:, 1] - coors[:, 0]
            val[:, 1] = coors[:, 0] + 3 * coors[:, 1]
            return val

        u.set_from_function(fun)

        coors = u.field.get_coor()
        eu = u.evaluate_at(coors)

        _ok = nm.allclose(eu, fun(coors), rtol=0.0, atol=1e-13)
        self.report('set from function:', _ok)
        ok = _ok and ok

        integral = Integral('i', order=2)
        gu_qp = u.evaluate(mode='grad', integral=integral)

        # du_i/dx_j, i = column, j = row.
        gu = nm.array([[-1., 1.], [2., 3.]])
        _ok = nm.allclose(gu_qp, gu[None, None, ...], rtol=0.0, atol=1e-13)
        self.report('set from function - gradient:', _ok)
        ok = _ok and ok

        u_qp = gu_qp[..., :, :1]
        u.set_from_qp(u_qp, integral)
        vu = u()

        _ok = (nm.allclose(vu[::2], -1, rtol=0.0, atol=1e-13)
               and nm.allclose(vu[1::2], 2, rtol=0.0, atol=1e-13))
        self.report('set from qp:', _ok)
        ok = _ok and ok

        return ok
Beispiel #18
0
    def create_subequations(self, var_names, known_var_names=None):
        """
        Create sub-equations containing only terms with the given virtual
        variables.

        Parameters
        ----------
        var_names : list
            The list of names of virtual variables.
        known_var_names : list
            The list of  names of (already) known state variables.

        Returns
        -------
        subequations : Equations instance
            The sub-equations.
        """
        from sfepy.discrete import FieldVariable

        known_var_names = get_default(known_var_names, [])

        objs = []
        for iv, var_name in enumerate(var_names):
            terms = [
                term.copy(name=term.name) for eq in self for term in eq.terms
                if term.get_virtual_name() == var_name
            ]

            # Make parameter variables from known state variables in terms
            # arguments.
            for known_name in known_var_names:
                for term in terms:
                    if known_name in term.arg_names:
                        ii = term.arg_names.index(known_name)
                        state = self.variables[known_name]
                        par = FieldVariable(known_name,
                                            'parameter',
                                            state.field,
                                            primary_var_name='(set-to-None)')
                        term.args[ii] = par
                        term._kwargs[known_name] = par
                        par.set_data(state())

            new_terms = Terms(terms)
            objs.append(Equation('eq_%d' % iv, new_terms))

        subequations = Equations(objs)

        return subequations
Beispiel #19
0
    def test_save_ebc(self):
        from sfepy.discrete import (FieldVariable, Integral, Equation,
                                    Equations, Problem)
        from sfepy.discrete.conditions import Conditions, EssentialBC
        from sfepy.terms import Term

        name = op.join(self.options.out_dir,
                       op.splitext(op.basename(__file__))[0])

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

        u = self.variables['u']
        v = FieldVariable('v', 'test', u.field, primary_var_name='u')

        p = self.variables['p']
        q = FieldVariable('q', 'test', p.field, primary_var_name='p')

        regions = self.problem.domain.regions
        omega = regions['Omega']

        # Problem.save_ebc() requires to have equations defined.
        t1 = Term.new('dw_lin_elastic(v, u)', integral, omega, v=v, u=u)
        t2 = Term.new('dw_laplace(q, p)', integral, omega, q=q, p=p)
        eq = Equation('aux', t1 + t2)
        eqs = Equations([eq])

        pb = Problem('test', equations=eqs, auto_solvers=False)

        all_ebcs = []
        all_ebcs.append(
            EssentialBC('fix_u1', regions['RightFix'],
                        {'u.all': nm.array([0.0, 1.0])}))
        all_ebcs.append(
            EssentialBC('fix_u2', regions['LeftStrip'], {
                'u.0': 0.0,
                'u.1': 1.0
            }))
        all_ebcs.append(
            EssentialBC('fix_p1', regions['LeftFix'], {'p.all': 0.0}))
        all_ebcs.append(
            EssentialBC('fix_p2', regions['RightStrip'], {'p.0': 0.0}))
        ebcs = Conditions(all_ebcs)

        pb.time_update(ebcs=ebcs)

        pb.save_ebc(name + '_ebcs_f.vtk', ebcs=ebcs, force=True)
        pb.save_ebc(name + '_ebcs.vtk', ebcs=ebcs, default=-1, force=False)

        return True
Beispiel #20
0
    def test_volume(self):
        from sfepy.discrete import FieldVariable

        ok = True

        field_map = {'u': 'vector', 'p': 'scalar'}

        volumes = {}
        avg = 0.0
        for key, term in expressions.items():
            var_name = key[-1]
            field = self.problem.fields[field_map[var_name]]
            var = FieldVariable(var_name,
                                'parameter',
                                field,
                                primary_var_name='(set-to-None)')

            val = self.problem.evaluate(term, **{var_name: var})

            volumes[key] = val
            avg += val

        avg /= len(volumes)

        for key, val in volumes.items():
            err = nm.abs(avg - val) / nm.abs(avg)
            _ok = err < 1e-12
            self.report('"' "%s" '" - volume: %e' % (key, val))
            self.report('"'
                        "%s"
                        '" - relative volume difference: %e -> %s' %
                        (key, err, _ok))
            ok = ok and _ok

        return ok
Beispiel #21
0
    def test_term_evaluation(self):
        from sfepy.discrete import Integral, FieldVariable
        from sfepy.terms.terms import Term

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

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

        term = Term.new('d_volume(u)', integral, self.omega, u=u)
        term *= 10.0

        term.setup()

        vol = term.evaluate()

        self.report('volume: %.8f == 2000.0' % vol)
        ok = nm.allclose(vol, 2000.0, rtol=1e-15, atol=0)

        ## vec = t1.evaluate() # Returns vector.
        ## vec = t1.evaluate(u=u_vec) # Returns the same vector.
        ## mtx = t1.evaluate(diff_var='u') # Returns matrix.
        ## val = t1.evaluate(v=u_vec, u=u_vec) # Forbidden - virtual variable
        ##                                     # cannot have value.

        return ok
Beispiel #22
0
    def test_term_arithmetics(self):
        from sfepy.discrete import FieldVariable, Integral
        from sfepy.terms.terms import Term

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

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

        t1 = Term.new('d_volume(u)', integral, self.omega, u=u)
        t2 = Term.new('d_surface(u)', integral, self.gamma1, u=u)

        expr = 2.2j * (t1 * 5.5 - 3j * t2) * 0.25

        ok = len(expr) == 2
        if not ok:
            self.report('wrong expression length!')

        _ok = nm.allclose(expr[0].sign, 3.025j, rtol=1e-15, atol=0)
        if not _ok:
            self.report('wrong sign of the first term!')
        ok = ok and _ok

        _ok = nm.allclose(expr[1].sign, 1.65, rtol=1e-15, atol=0)
        if not _ok:
            self.report('wrong sign of the second term!')
        ok = ok and _ok

        return ok
Beispiel #23
0
    def create_subequations(self, var_names, known_var_names=None):
        """
        Create sub-equations containing only terms with the given virtual
        variables.

        Parameters
        ----------
        var_names : list
            The list of names of virtual variables.
        known_var_names : list
            The list of  names of (already) known state variables.

        Returns
        -------
        subequations : Equations instance
            The sub-equations.
        """
        from sfepy.discrete import FieldVariable

        known_var_names = get_default(known_var_names, [])

        objs = []
        for iv, var_name in enumerate(var_names):
            terms = [term.copy(name=term.name)
                     for eq in self for term in eq.terms
                     if term.get_virtual_name() == var_name]

            # Make parameter variables from known state variables in terms
            # arguments.
            for known_name in known_var_names:
                for term in terms:
                    if known_name in term.arg_names:
                        ii = term.arg_names.index(known_name)
                        state = self.variables[known_name]
                        par = FieldVariable(known_name, 'parameter',
                                            state.field,
                                            primary_var_name='(set-to-None)')
                        term.args[ii] = par
                        term._kwargs[known_name] = par
                        par.set_data(state())

            new_terms = Terms(terms)
            objs.append(Equation('eq_%d' % iv, new_terms))

        subequations = Equations(objs)

        return subequations
Beispiel #24
0
    def test_variables(self):
        from sfepy.discrete import FieldVariable

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

        u.set_constant(1.0)

        vec = u() # Nodal values.

        ok = nm.allclose(vec, 1.0)

        ## print u() 
        ## print u.get_vector() # Coefficient vector w.r.t. the field space basis.
        ## print u(gamma1)
        ## print u.get_vector(gamma2)

        return ok
Beispiel #25
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 #26
0
    def test_variables(self):
        from sfepy.discrete import FieldVariable

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

        u.set_constant(1.0)

        vec = u() # Nodal values.

        ok = nm.allclose(vec, 1.0)

        ## print u()
        ## print u.get_vector() # Coefficient vector w.r.t. the field space basis.
        ## print u(gamma1)
        ## print u.get_vector(gamma2)

        return ok
Beispiel #27
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 #28
0
def make_h1_projection_data(target, eval_data):
    """
    Project scalar data given by a material-like `eval_data()` function to a
    scalar `target` field variable using the :math:`H^1` dot product.
    """
    order = target.field.approx_order * 2
    integral = Integral('i', order=order)

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

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

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

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

    ls = ScipyDirect({})

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

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

    pb.time_update()

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

    if nls_status.condition != 0:
        output('H1 projection: solver did not converge!')
Beispiel #29
0
    def test_variables(self):
        from sfepy.discrete import FieldVariable, Integral

        ok = True

        u = FieldVariable('u', 'parameter', self.field,
                          primary_var_name='(set-to-None)')
        u.set_constant(1.0)
        vec = u() # Nodal values.

        _ok = nm.allclose(vec, 1.0)
        self.report('set constant:', _ok)
        ok = _ok and ok

        def fun(coors):
            val = nm.empty_like(coors)
            val[:, 0] = 2 * coors[:, 1] - coors[:, 0]
            val[:, 1] = coors[:, 0] + 3 * coors[:, 1]
            return val
        u.set_from_function(fun)

        coors = u.field.get_coor()
        eu = u.evaluate_at(coors)

        _ok = nm.allclose(eu, fun(coors), rtol=0.0, atol=1e-13)
        self.report('set from function:', _ok)
        ok = _ok and ok

        integral = Integral('i', order=2)
        gu_qp = u.evaluate(mode='grad', integral=integral)

        # du_i/dx_j, i = column, j = row.
        gu = nm.array([[-1.,  1.],
                       [ 2.,  3.]])
        _ok = nm.allclose(gu_qp, gu[None, None, ...], rtol=0.0, atol=1e-13)
        self.report('set from function - gradient:', _ok)
        ok = _ok and ok

        u_qp = gu_qp[..., :, :1]
        u.set_from_qp(u_qp, integral)
        vu = u()

        _ok = (nm.allclose(vu[::2], -1, rtol=0.0, atol=1e-13) and
               nm.allclose(vu[1::2], 2, rtol=0.0, atol=1e-13))
        self.report('set from qp:', _ok)
        ok = _ok and ok

        return ok
Beispiel #30
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
Beispiel #31
0
def linear_projection(pb, cval):
    from sfepy.discrete import (FieldVariable, Material, Integral, Equation,
                                Equations, Problem)
    from sfepy.discrete.fem import Mesh, FEDomain, Field
    from sfepy.terms import Term
    from sfepy.solvers.ls import ScipyDirect
    from sfepy.solvers.nls import Newton
    from sfepy.base.base import IndexedStruct

    mesh = Mesh.from_file(pb.conf.filename_mesh)
    domain = FEDomain('domain', mesh)
    omega = domain.create_region('Omega', 'all')
    field = Field.from_args('scf', nm.float64, 'scalar', omega, approx_order=1)

    g = FieldVariable('g', 'unknown', field)
    f = FieldVariable('f', 'test', field, primary_var_name='g')

    integral = Integral('i', order=2)
    m = Material('m', function=set_grad)

    t1 = Term.new('dw_volume_dot(f, g)', integral, omega, f=f, g=g)
    t2 = Term.new('dw_volume_lvf(m.cs, f)', integral, omega, m=m, f=f)
    eq = Equation('balance', t1 - t2)
    eqs = Equations([eq])
    ls = ScipyDirect({})

    nls_status = IndexedStruct()
    nls = Newton({'eps_a': 1e-15}, lin_solver=ls, status=nls_status)
    pb = Problem('elasticity', equations=eqs)
    pb.set_solver(nls)

    out = nm.empty((g.n_dof, cval.shape[2]), dtype=nm.float64)
    for ii in range(cval.shape[2]):
        pb.data = nm.ascontiguousarray(cval[:, :, ii, :])
        pb.time_update()
        state = pb.solve()
        out[:, ii] = state.get_parts()['g']

    return out
Beispiel #32
0
    def test_project_tensors(self):
        from sfepy.discrete import FieldVariable
        from sfepy.discrete.projections import project_by_component

        ok = True

        u = FieldVariable('u', 'parameter', self.field,
                          primary_var_name='(set-to-None)')
        u.set_constant(1.0)

        component = FieldVariable('component', 'parameter', self.field,
                                  primary_var_name='(set-to-None)')

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

        u_qp = u.evaluate()
        u2 = FieldVariable('u2', 'parameter', self.field,
                           primary_var_name='(set-to-None)')
        project_by_component(u2, u_qp, component, self.field.approx_order,
                             nls_options=nls_options)

        _ok = self.compare_vectors(u(), u2())
        ok = ok and _ok

        gu_qp = u.evaluate(mode='grad')

        gfield = Field.from_args('gu', nm.float64, 2, self.field.region,
                                 approx_order=self.field.approx_order)
        gu = FieldVariable('gu', 'parameter', gfield,
                           primary_var_name='(set-to-None)')

        project_by_component(gu, gu_qp, component, gfield.approx_order,
                             nls_options=nls_options)

        _ok = self.compare_vectors(gu(), nm.zeros_like(gu()))
        ok = ok and _ok

        return ok
def verify_save_dof_maps(field,
                         cell_tasks,
                         dof_maps,
                         id_map,
                         options,
                         verbose=False):
    vec = pl.verify_task_dof_maps(dof_maps, id_map, field, verbose=verbose)

    order = options.order
    mesh = field.domain.mesh

    sfield = Field.from_args('aux',
                             nm.float64,
                             'scalar',
                             field.region,
                             approx_order=order)
    aux = FieldVariable('aux',
                        'parameter',
                        sfield,
                        primary_var_name='(set-to-None)')
    out = aux.create_output(vec,
                            linearization=Struct(kind='adaptive',
                                                 min_level=order - 1,
                                                 max_level=order - 1,
                                                 eps=1e-8))

    filename = os.path.join(options.output_dir, 'para-domains-dofs.h5')
    if field.is_higher_order():
        out['aux'].mesh.write(filename, out=out)

    else:
        mesh.write(filename, out=out)

    out = Struct(name='cells',
                 mode='cell',
                 data=cell_tasks[:, None, None, None])
    filename = os.path.join(options.output_dir, 'para-domains-cells.h5')
    mesh.write(filename, out={'cells': out})
Beispiel #34
0
def get_fields(shape, delta_x):
    """Get the fields for the displacement and test function

    Args:
      shape: the shape of the domain
      delta_x: the mesh spacing

    Returns:
      tuple of field variables
    """
    return pipe(
        np.array(shape),
        lambda x: gen_block_mesh(
            x * delta_x, x + 1, np.zeros_like(shape), verbose=False
        ),
        lambda x: Domain("domain", x),
        lambda x: x.create_region("region_all", "all"),
        lambda x: Field.from_args("fu", np.float64, "vector", x, approx_order=2),
        lambda x: (
            FieldVariable("u", "unknown", x),
            FieldVariable("v", "test", x, primary_var_name="u"),
        ),
    )
Beispiel #35
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 #36
0
def create_mass_matrix(field):
    """
    Create scalar mass matrix corresponding to the given field.

    Returns
    -------
    mtx : csr_matrix
        The mass matrix in CSR format.
    """
    u = FieldVariable('u', 'unknown', field)
    v = FieldVariable('v', 'test', field, primary_var_name='u')

    integral = Integral('i', order=field.approx_order * 2)
    term = Term.new('dw_volume_dot(v, u)', integral, field.region, v=v, u=u)
    eq = Equation('aux', term)
    eqs = Equations([eq])
    eqs.time_update(None)

    dummy = eqs.create_state_vector()

    mtx = eqs.create_matrix_graph()
    mtx = eqs.eval_tangent_matrices(dummy, mtx)

    return mtx
Beispiel #37
0
def get_volume(problem, field_name, region_name, quad_order=1):
    """
    Get volume of a given region using integration defined by a given
    field. Both the region and the field have to be defined in
    `problem`.
    """
    from sfepy.discrete import FieldVariable

    field = problem.fields[field_name]
    var = FieldVariable('u',
                        'parameter',
                        field,
                        1,
                        primary_var_name='(set-to-None)')

    vol = problem.evaluate('d_volume.%d.%s( u )' % (quad_order, region_name),
                           u=var)

    return vol
Beispiel #38
0
    def test_continuity(self):
        from sfepy.base.base import Struct
        from sfepy.mesh.mesh_generators import gen_block_mesh
        from sfepy.discrete import FieldVariable
        from sfepy.discrete.fem import FEDomain, Field
        from sfepy.discrete.projections import make_l2_projection_data
        import sfepy.discrete.fem.refine_hanging as rh

        dims = [1.5, 2.0, 1.3]
        shape = [3, 3, 3]
        centre = [0.0, 0.0, 0.0]
        probe_gens = {"2_4": _gen_lines_2_4, "3_8": _gen_grid_3_8}

        ok = True
        for key in self.gel_names:
            gel = self.gels[key]
            probe_gen = probe_gens[key]

            perms = gel.get_conn_permutations()

            dim = gel.dim
            for io, order in enumerate(range(1, 4)):
                mesh00 = gen_block_mesh(dims[:dim], shape[:dim], centre[:dim], name="block")

                for ip, perm in enumerate(perms):
                    self.report("geometry: %s, order: %d, permutation: %d: %s" % (key, order, ip, perm))
                    mesh0 = mesh00.copy()
                    conn = mesh0.cmesh.get_conn(dim, 0).indices
                    conn = conn.reshape((mesh0.n_el, -1))
                    conn[-1, :] = conn[-1, perm]

                    domain0 = FEDomain("d", mesh0)

                    refine = nm.zeros(mesh0.n_el, dtype=nm.uint8)
                    refine[:-1] = 1

                    subs = None
                    domain, subs = rh.refine(domain0, refine, subs=subs)

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

                    field.substitute_dofs(subs)

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

                    field.restore_dofs(store=True)
                    field.substitute_dofs(subs=None, restore=True)

                    make_l2_projection_data(uvar, eval_fun)

                    field.restore_dofs()

                    bbox = domain.get_mesh_bounding_box()
                    eps = 1e-7

                    save = False
                    for ii, (probe0, probe1) in enumerate(probe_gen(bbox, eps)):
                        probe0.set_options(close_limit=0.0)
                        probe1.set_options(close_limit=0.0)

                        pars0, vals0 = probe0(uvar)
                        pars1, vals1 = probe1(uvar)

                        assert_(nm.allclose(pars0, pars1, atol=1e-14, rtol=0.0))

                        _ok = nm.allclose(vals0, vals1, atol=20.0 * eps, rtol=0.0)
                        if not _ok:
                            save = True
                            self.report("probe %d failed! (max. error: %e)" % (ii, nm.abs(vals0 - vals1).max()))

                        ok = ok and _ok

                    if (ip == 0) or save:
                        out = uvar.create_output()
                        filenames = _build_filenames(self.options.out_dir, key, order, ip)

                        domain.mesh.write(filenames[0], out=out)

                        linearization = Struct(kind="adaptive", min_level=0, max_level=4, eps=1e-2)

                        out = uvar.create_output(linearization=linearization)
                        val = out["u"]
                        mesh = val.get("mesh", domain.mesh)
                        mesh.write(filenames[1], out=out)

        return ok
Beispiel #39
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 #40
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 #41
0
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
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)

    stats = Struct()
    timer = Timer('solve_timer')

    timer.start()
    mesh = Mesh.from_file(mesh_filename)
    stats.t_read_mesh = timer.stop()

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

    else:
        cell_tasks = None

    stats.t_partition_mesh = timer.stop()

    output('creating global domain and fields...')
    timer.start()

    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]

    stats.t_create_global_fields = timer.stop()
    output('...done in', timer.dt)

    output('distributing fields...')
    timer.start()

    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)

    stats.t_distribute_fields_dofs = timer.stop()
    output('...done in', timer.dt)

    output('creating local problem...')
    timer.start()

    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()

    stats.t_create_local_problem = timer.stop()
    output('...done in', timer.dt)

    output('allocating global system...')
    timer.start()

    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)

    stats.t_allocate_global_system = timer.stop()
    output('...done in', timer.dt)

    output('creating solver...')
    timer.start()

    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)

    stats.t_create_solver = timer.stop()
    output('...done in', timer.dt)

    output('solving...')
    timer.start()

    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[...]

    stats.t_solve = timer.stop()
    output('...done in', timer.dt)

    output('saving solution...')
    timer.start()

    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)

    stats.t_save_solution = timer.stop()
    output('...done in', timer.dt)

    stats.t_total = timer.total

    stats.n_dof = sizes[1]
    stats.n_dof_local = sizes[0]
    stats.n_cell = omega.shape.n_cell
    stats.n_cell_local = omega_gi.shape.n_cell

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

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

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

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

            elif sh == 'S':
                return sym

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

            else:
                return int(sh)

        else:
            return sh

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

        else:
            return (int(sh),)

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

            else:
                extended_ats = arg_types[ii]

            try:
                sh = arg_shapes[arg_types[ii]]

            except KeyError:
                sh = arg_shapes[extended_ats]

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

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

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

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

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

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

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

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

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

            if material_value is None:
                material_value = 1.0

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

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

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

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

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

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

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

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

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

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

    return args, str_args, materials, variables
Beispiel #44
0
def main():
    from sfepy import data_dir

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

    mesh = Mesh.from_file(data_dir + '/meshes/2d/rectangle_tri.mesh')
    domain = 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 #45
0
def make_term_args(arg_shapes,
                   arg_kinds,
                   arg_types,
                   ats_mode,
                   domain,
                   material_value=None,
                   poly_space_base=None):
    from sfepy.base.base import basestr
    from sfepy.discrete import FieldVariable, Material, Variables, Materials
    from sfepy.discrete.fem import Field
    from sfepy.solvers.ts import TimeStepper
    from sfepy.mechanics.tensors import dim2sym

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

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

            elif sh == 'S':
                return sym

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

            else:
                return int(sh)

        else:
            return sh

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

        else:
            return (int(sh), )

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

            else:
                extended_ats = arg_types[ii]

            try:
                sh = arg_shapes[arg_types[ii]]

            except KeyError:
                sh = arg_shapes[extended_ats]

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

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

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

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

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

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

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

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

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

            if material_value is None:
                material_value = 1.0

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

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

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

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

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

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

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

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

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

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

    return args, str_args, materials, variables
def main():
    parser = ArgumentParser(description=__doc__.rstrip(),
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('output_dir', help=helps['output_dir'])
    parser.add_argument('--dims', metavar='dims',
                        action='store', dest='dims',
                        default='1.0,1.0,1.0', help=helps['dims'])
    parser.add_argument('--shape', metavar='shape',
                        action='store', dest='shape',
                        default='7,7,7', help=helps['shape'])
    parser.add_argument('--centre', metavar='centre',
                        action='store', dest='centre',
                        default='0.0,0.0,0.0', help=helps['centre'])
    parser.add_argument('-3', '--3d',
                        action='store_true', dest='is_3d',
                        default=False, help=helps['3d'])
    parser.add_argument('--order', metavar='int', type=int,
                        action='store', dest='order',
                        default=1, help=helps['order'])
    options = parser.parse_args()

    dim = 3 if options.is_3d else 2
    dims = nm.array(eval(options.dims), dtype=nm.float64)[:dim]
    shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim]
    centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim]

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

    mesh0 = gen_block_mesh(dims, shape, centre, name='block-fem',
                           verbose=True)
    domain0 = FEDomain('d', mesh0)

    bbox = domain0.get_mesh_bounding_box()
    min_x, max_x = bbox[:, 0]
    eps = 1e-8 * (max_x - min_x)

    cnt = (shape[0] - 1) // 2
    g0 = 0.5 * dims[0]
    grading = nm.array([g0 / 2**ii for ii in range(cnt)]) + eps + centre[0] - g0

    domain, subs = refine_towards_facet(domain0, grading, '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, 1, omega,
                            approx_order=options.order)

    if subs is not None:
        field.substitute_dofs(subs)

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

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

    t1 = Term.new('dw_laplace(v, u)',
                  integral, omega, v=v, u=u)
    eq = Equation('eq', t1)
    eqs = Equations([eq])

    def u_fun(ts, coors, bc=None, problem=None):
        """
        Define a displacement depending on the y coordinate.
        """
        if coors.shape[1] == 2:
            min_y, max_y = bbox[:, 1]
            y = (coors[:, 1] - min_y) / (max_y - min_y)

            val = (max_y - min_y) * nm.cos(3 * nm.pi * y)

        else:
            min_y, max_y = bbox[:, 1]
            min_z, max_z = bbox[:, 2]
            y = (coors[:, 1] - min_y) / (max_y - min_y)
            z = (coors[:, 2] - min_z) / (max_z - min_z)

            val = ((max_y - min_y) * (max_z - min_z)
                   * nm.cos(3 * nm.pi * y) * (1.0 + 3.0 * (z - 0.5)**2))

        return val

    bc_fun = Function('u_fun', u_fun)
    fix1 = EssentialBC('shift_u', gamma1, {'u.0' : bc_fun})
    fix2 = EssentialBC('fix2', gamma2, {'u.all' : 0.0})

    ls = ScipyDirect({})

    nls = Newton({}, lin_solver=ls)

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

    pb.time_update(ebcs=Conditions([fix1, fix2]))
    state = pb.solve()

    if subs is not None:
        field.restore_dofs()

    filename = os.path.join(options.output_dir, 'hanging.vtk')
    ensure_path(filename)

    pb.save_state(filename, state)
    if options.order > 1:
        pb.save_state(filename, state, linearization=Struct(kind='adaptive',
                                                            min_level=0,
                                                            max_level=8,
                                                            eps=1e-3))
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)