Beispiel #1
0
    def _get_periodicBC_X(self, domain, dim):
        dim_dict = {1: ('y', per.match_y_plane),
                    2: ('z', per.match_z_plane)}
        dim_string = dim_dict[dim][0]
        match_plane = dim_dict[dim][1]
        min_, max_ = domain.get_mesh_bounding_box()[:, dim]
        min_x, max_x = domain.get_mesh_bounding_box()[:, 0]
        plus_ = self._subdomain_func(max_x=max_x, **{dim_string: (max_,)})
        minus_ = self._subdomain_func(max_x=max_x, **{dim_string: (min_,)})
        plus_string = dim_string + 'plus'
        minus_string = dim_string + 'minus'
        plus = Function(plus_string, plus_)
        minus = Function(minus_string, minus_)
        region_plus = domain.create_region(
            'region_{0}_plus'.format(dim_string),
            'vertices by {0}'.format(
                plus_string),
            'facet',
            functions=Functions([plus]))
        region_minus = domain.create_region(
            'region_{0}_minus'.format(dim_string),
            'vertices by {0}'.format(
                minus_string),
            'facet',
            functions=Functions([minus]))
        match_plane = Function(
            'match_{0}_plane'.format(dim_string), match_plane)

        bc_dict = {'u.0': 'u.0'}

        bc = PeriodicBC('periodic_{0}'.format(dim_string),
                        [region_plus, region_minus],
                        bc_dict,
                        match='match_{0}_plane'.format(dim_string))
        return bc, match_plane
Beispiel #2
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
Beispiel #3
0
    def _get_fixed_displacementsBCs(self, domain):
        """
        Fix the left top and bottom points in x, y and z

        Args:
          domain: an Sfepy domain

        Returns:
          the Sfepy boundary conditions

        """
        min_xyz = domain.get_mesh_bounding_box()[0]
        max_xyz = domain.get_mesh_bounding_box()[1]

        kwargs = {}
        fix_points_dict = {'u.0': 0.0, 'u.1': 0.0}
        if len(min_xyz) == 3:
            kwargs = {'z': (max_xyz[2], min_xyz[2])}
            fix_points_dict['u.2'] = 0.0
        fix_x_points_ = self._subdomain_func(x=(min_xyz[0],),
                                             y=(max_xyz[1], min_xyz[1]),
                                             **kwargs)

        fix_x_points = Function('fix_x_points', fix_x_points_)
        region_fix_points = domain.create_region(
            'region_fix_points',
            'vertices by fix_x_points',
            'vertex',
            functions=Functions([fix_x_points]))
        return EssentialBC('fix_points_BC', region_fix_points, fix_points_dict)
Beispiel #4
0
    def _get_shift_displacementsBCs(self, domain):
        """
        Fix the right top and bottom points in x, y and z

        Args:
          domain: an Sfepy domain

        Returns:
          the Sfepy boundary conditions

        """
        min_xyz = domain.get_mesh_bounding_box()[0]
        max_xyz = domain.get_mesh_bounding_box()[1]
        kwargs = {}
        if len(min_xyz) == 3:
            kwargs = {'z': (max_xyz[2], min_xyz[2])}

        displacement = self.macro_strain * (max_xyz[0] - min_xyz[0])
        shift_points_dict = {'u.0': displacement}

        shift_x_points_ = self._subdomain_func(x=(max_xyz[0],),
                                               y=(max_xyz[1], min_xyz[1]),
                                               **kwargs)

        shift_x_points = Function('shift_x_points', shift_x_points_)
        region_shift_points = domain.create_region(
            'region_shift_points',
            'vertices by shift_x_points',
            'vertex',
            functions=Functions([shift_x_points]))
        return EssentialBC('shift_points_BC',
                           region_shift_points, shift_points_dict)
    def eval_force(region_name):
        strain = problem.evaluate(
            'ev_cauchy_strain.i.%s(u)' % region_name,
            mode='qp',
            verbose=False,
        )
        D = problem.evaluate(
            'ev_integrate_mat.i.%s(solid.D, u)' % region_name,
            mode='qp',
            verbose=False,
        )

        normal = nm.array([1, 0, 0], dtype=nm.float64)

        s2f = get_full_indices(len(normal))
        stress = nm.einsum('cqij,cqjk->cqik', D, strain)
        # Full (matrix) form of stress.
        mstress = stress[..., s2f, 0]

        # Force in normal direction.
        force = nm.einsum('cqij,i,j->cq', mstress, normal, normal)

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

        aux = Material('aux', function=Function('get_force', get_force))

        middle_force = -problem.evaluate(
            'ev_integrate_mat.i.%s(aux.force, u)' % region_name,
            aux=aux,
            verbose=False,
        )
        output('%s section axial force:' % region_name, middle_force)
Beispiel #6
0
def get_bc(max_x_func, domain, dim, bc_dict_func):
    """Get the periodic boundary condition

    Args:
      max_x_func: function for finding the maximum value of x
      domain: the Sfepy domain
      dim: the x, y or z direction
      bc_dict_func: function to generate the bc dict

    Returns:
      the boundary condition and the sfepy function
    """
    dim_dict = lambda x: [
        ("x", per.match_x_plane),
        ("y", per.match_y_plane),
        ("z", per.match_z_plane),
    ][dim][x]
    return pipe(
        domain.get_mesh_bounding_box(),
        lambda x: PeriodicBC(
            "periodic_{0}".format(dim_dict(0)),
            list(
                map_(
                    get_region_func(max_x_func(x), dim_dict(0), domain),
                    zip(("plus", "minus"), x[:, dim][::-1]),
                )
            ),
            bc_dict_func(x),
            match="match_{0}_plane".format(dim_dict(0)),
        ),
        lambda x: (x, Function("match_{0}_plane".format(dim_dict(0)), dim_dict(1))),
    )
Beispiel #7
0
    def _get_material(self, property_array, domain):
        """
        Creates an SfePy material from the material property fields for the
        quadrature points.

        Args:
          property_array: array of the properties with shape (n_x, n_y, n_z, 2)

        Returns:
          an SfePy material

        """
        min_xyz = domain.get_mesh_bounding_box()[0]
        dims = domain.get_mesh_bounding_box().shape[1]

        def _material_func_(ts, coors, mode=None, **kwargs):
            if mode == 'qp':
                ijk_out = np.empty_like(coors, dtype=int)
                ijk = np.floor((coors - min_xyz[None]) / self.dx,
                               ijk_out, casting="unsafe")
                ijk_tuple = tuple(ijk.swapaxes(0, 1))
                property_array_qp = property_array[ijk_tuple]
                lam = property_array_qp[..., 0]
                mu = property_array_qp[..., 1]
                lam = np.ascontiguousarray(lam.reshape((lam.shape[0], 1, 1)))
                mu = np.ascontiguousarray(mu.reshape((mu.shape[0], 1, 1)))

                from sfepy.mechanics.matcoefs import stiffness_from_lame
                stiffness = stiffness_from_lame(dims, lam=lam, mu=mu)
                return {'lam': lam, 'mu': mu, 'D': stiffness}
            else:
                return

        material_func = Function('material_func', _material_func_)
        return Material('m', function=material_func)
Beispiel #8
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 #9
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 #10
0
    def func(min_xyz, max_xyz):
        def shift_(_, coors, __):
            return np.ones_like(coors[:, 0]) * macro_strain * (max_xyz[0] - min_xyz[0])

        return pipe(
            [("plus", max_xyz[0]), ("minus", min_xyz[0])],
            map_(get_region_func(None, "x", domain)),
            list,
            lambda x: LinearCombinationBC(
                "lcbc",
                x,
                {"u.0": "u.0"},
                Function("match_x_plane", per.match_x_plane),
                "shifted_periodic",
                arguments=(Function("shift", shift_),),
            ),
            lambda x: Conditions([x]),
        )
    def _get_linear_combinationBCs(self, domain):
        """
        The right nodes are periodic with the left nodes but also displaced.

        Args:
          domain: an Sfepy domain

        Returns:
          the Sfepy boundary conditions

        """
        min_xyz = domain.get_mesh_bounding_box()[0]
        max_xyz = domain.get_mesh_bounding_box()[1]
        xplus_ = self._subdomain_func(x=(max_xyz[0], ))
        xminus_ = self._subdomain_func(x=(min_xyz[0], ))

        xplus = Function('xplus', xplus_)
        xminus = Function('xminus', xminus_)
        region_x_plus = domain.create_region('region_x_plus',
                                             'vertices by xplus',
                                             'facet',
                                             functions=Functions([xplus]))
        region_x_minus = domain.create_region('region_x_minus',
                                              'vertices by xminus',
                                              'facet',
                                              functions=Functions([xminus]))
        match_x_plane = Function('match_x_plane', per.match_x_plane)

        def shift_(ts, coors, region):
            return np.ones_like(
                coors[:, 0]) * self.macro_strain * (max_xyz[0] - min_xyz[0])

        shift = Function('shift', shift_)
        lcbc = LinearCombinationBC('lcbc', [region_x_plus, region_x_minus],
                                   {'u.0': 'u.0'},
                                   match_x_plane,
                                   'shifted_periodic',
                                   arguments=(shift, ))

        return Conditions([lcbc])
Beispiel #12
0
def get_material(calc_stiffness, calc_prestress):
    """Get the material

    Args:
      calc_stiffness: the function for calculating the stiffness tensor
      calc_prestress: the function for calculating the prestress

    Returns:
      the material
    """

    def _material_func_(_, coors, mode=None, **__):
        if mode == "qp":
            return dict(D=calc_stiffness(coors), stress=calc_prestress(coors))
        return None

    return Material("m", function=Function("material_func", _material_func_))
Beispiel #13
0
 def func(min_xyz, max_xyz):
     return pipe(
         dict(z_points=(max_xyz[2], min_xyz[2])) if len(min_xyz) == 3 else dict(),
         lambda x: subdomain_func(
             x_points=x_points_f(min_xyz, max_xyz),
             y_points=(max_xyz[1], min_xyz[1]),
             **x,
         ),
         lambda x: Function(f"{name}_x_points", x),
         lambda x: domain.create_region(
             f"region_{name}_points",
             f"vertices by {name}_x_points",
             "vertex",
             functions=Functions([x]),
         ),
         lambda x: EssentialBC(
             f"{name}_points_BC", x, points_dict_f(min_xyz, max_xyz)
         ),
     )
Beispiel #14
0
def _get_material(property_array, domain, delta_x):
    """
    Creates an SfePy material from the material property fields for the
    quadrature points.

    Args:
      property_array: array of the properties with shape (n_x, n_y, n_z, 2)
      domain: the Sfepy domain
      delta_x: the grid spacing

    Returns:
      a SfePy material

    """
    reshape = lambda x: np.ascontiguousarray(x.reshape((x.shape[0], 1, 1)))

    def _material_func_(_, coors, mode=None, **__):
        if mode == "qp":
            return pipe(
                np.empty_like(coors, dtype=int),
                lambda x: np.floor(
                    (coors - domain.get_mesh_bounding_box()[0][None]) /
                    delta_x,
                    x,
                    casting="unsafe",
                ),
                lambda x: x.swapaxes(0, 1),
                tuple,
                lambda x: property_array[x],
                lambda x: dict(
                    lam=reshape(x[..., 0]),
                    mu=reshape(x[..., 1]),
                    D=stiffness_from_lame(
                        domain.get_mesh_bounding_box().shape[1],
                        lam=x[..., 0],
                        mu=x[..., 1],
                    ),
                ),
            )
        return None

    return Material("m", function=Function("material_func", _material_func_))
Beispiel #15
0
def get_region_func(max_x, dim_string, domain, name_minmax):
    """Generate the Sfepy region

    Args:
      max_x: max value in the x direction
      dim_string: either "x", "y", or "z"
      domain: the Sfepy domain
      name_minmax: tuple of name and min / max

    Returns:
      the Sfepy region
    """
    return pipe(
        subdomain_func(max_x=max_x, **{dim_string + "_points": (name_minmax[1],)}),
        lambda x: Function(dim_string + name_minmax[0], x),
        lambda x: domain.create_region(
            "region_{0}_{1}".format(dim_string, name_minmax[0]),
            "vertices by {0}".format(x.name),
            "facet",
            functions=Functions([x]),
        ),
    )
Beispiel #16
0
def get_bc(domain, delta_x, index, cond):
    """Make a displacement boundary condition

    Args:
      domain: the Sfepy domain
      delta_x: the mesh spacing
      index: the index (either 0 or 1) depends on direction of axes
      cond: the BC dictionary

    Returns:
      the Sfepy boundary condition
    """
    return pipe(
        Function("fix_points", subdomain(index, domain, delta_x * 1e-3)),
        lambda x: domain.create_region(
            "region_fix_points",
            "vertices by fix_points",
            "vertex",
            functions=Functions([x]),
        ),
        lambda x: EssentialBC("fix_points_BC", x, cond),
    )
Beispiel #17
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)
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))
Beispiel #19
0
def main(argv=None):
    options = parse_args(argv=argv)

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

    # Setup output names
    outputs_folder = options.output_dir

    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 = Term.new('dw_dot(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 = Term.new('dw_ns_dot_grad_s(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 = Term.new('dw_dg_nonlinear_laxfrie_flux(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|
    # ----------
    if options.plot:
        load_and_plot_fun(output_folder, domain_name, t0, t1,
                          min(tn, save_timestn), ic_fun)
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 xrange(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 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 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])
def find_level_interface(domain, refine_flag):
    """
    Find facets of the coarse mesh that are on the coarse-refined cell
    boundary.

    ids w.r.t. current mesh:
    - facets: global, local w.r.t. cells[:, 0], local w.r.t. cells[:, 1]

    - interface cells:
      - cells[:, 0] - cells to refine
      - cells[:, 1] - their facet sharing neighbors (w.r.t. both meshes)
      - cells[:, 2] - facet kind: 0 = face, 1 = edge
    """
    if not refine_flag.any():
        facets = nm.zeros((0, 3), dtype=nm.uint32)
        cells = nm.zeros((0, 3), dtype=nm.uint32)
        return facets, cells, 0, None, None

    def _get_refine(coors, domain=None):
        return nm.nonzero(refine_flag)[0]

    def _get_coarse(coors, domain=None):
        return nm.nonzero(1 - refine_flag)[0]

    get_refine = Function('get_refine', _get_refine)
    get_coarse = Function('get_coarse', _get_coarse)
    functions = Functions([get_refine, get_coarse])
    region0 = domain.create_region('coarse',
                                   'cells by get_coarse',
                                   functions=functions,
                                   add_to_regions=False,
                                   allow_empty=True)
    region1 = domain.create_region('refine',
                                   'cells by get_refine',
                                   functions=functions,
                                   add_to_regions=False)

    cmesh = domain.mesh.cmesh
    dim = cmesh.dim

    if dim == 2:
        oe = 0

        facets = nm.intersect1d(region0.facets, region1.facets)

        cmesh.setup_connectivity(dim - 1, dim)
        cells, offs = cmesh.get_incident(dim,
                                         facets,
                                         dim - 1,
                                         ret_offsets=True)
        assert_((nm.diff(offs) == 2).all())

        ii = cmesh.get_local_ids(facets, dim - 1, cells, offs, dim)

        ii = ii.reshape((-1, 2))
        cells = cells.reshape((-1, 2))

        ii = nm.where(refine_flag[cells], ii[:, :1], ii[:, 1:])
        cells = nm.where(refine_flag[cells], cells[:, :1], cells[:, 1:])

        facets = nm.c_[facets, ii]

        cells = nm.c_[cells, nm.zeros_like(cells[:, 1])]

    else:  # if dim == 3:
        gel = domain.geom_els['3_8']
        epf = gel.get_edges_per_face()

        cmesh.setup_connectivity(dim, dim)
        fc, coffs = cmesh.get_incident(dim,
                                       region1.cells,
                                       dim,
                                       ret_offsets=True)
        cc = nm.repeat(region1.cells, nm.diff(coffs))
        aux = nm.c_[cc, fc]
        """
        nnn[:, 0] cells to refine, nnn[:, 1] non-refined neighbours, nnn[:, 2]
        neighbour kind : 0 face, 1 edge.
        """
        nn = aux[refine_flag[fc] == 0]

        cf = nn[:, 0].copy().astype(nm.uint32)
        cc = nn[:, 1].copy().astype(nm.uint32)

        vc, vco = cmesh.get_incident(0, cc, dim, ret_offsets=True)
        vf, vfo = cmesh.get_incident(0, cf, dim, ret_offsets=True)
        vc = vc.reshape((-1, 8))
        vf = vf.reshape((-1, 8))

        nnn = []
        oe = 0
        ov = nn.shape[0]
        for ii in range(vc.shape[0]):
            aux = set(vc[ii]).intersection(vf[ii])
            nc = len(aux)
            if nc == 1:
                nnn.append((0, 0, 2))
                ov -= 1

            elif nc == 4:
                nnn.append((nn[ii, 0], nn[ii, 1], 0))
                oe += 1

            else:
                nnn.append((nn[ii, 0], nn[ii, 1], 1))
        nnn = nm.array(nnn)

        if nnn.shape[0] == 0:
            facets = nm.zeros((0, 3), dtype=nm.uint32)
            cells = nm.zeros((0, 4), dtype=nm.uint32)

            return facets, cells, 0, region0, region1

        # Sort by neighbour kind, skip vertex-only neighbours.
        ii = nm.argsort(nnn[:, 2])
        nnn = nnn[ii][:ov]
        cf = cf[ii][:ov]
        cc = cc[ii][:ov]

        ec, eco = cmesh.get_incident(1, cc, dim, ret_offsets=True)
        ef, efo = cmesh.get_incident(1, cf, dim, ret_offsets=True)
        ec = ec.reshape((-1, 12))
        ef = ef.reshape((-1, 12))

        fc, fco = cmesh.get_incident(2, cc, dim, ret_offsets=True)
        ff, ffo = cmesh.get_incident(2, cf, dim, ret_offsets=True)
        fc = fc.reshape((-1, 6))
        ff = ff.reshape((-1, 6))

        emask = nm.zeros((domain.shape.n_el, 12), dtype=nm.bool)

        ffs = []
        for ii in range(oe):
            facet = nm.intersect1d(fc[ii], ff[ii])[0]
            i1 = nm.where(ff[ii] == facet)[0][0]
            i0 = nm.where(fc[ii] == facet)[0][0]
            ffs.append((facet, i1, i0))

            emask[nnn[ii, 0], epf[i1]] = True

        for ii in range(oe, nnn.shape[0]):
            facet = nm.intersect1d(ec[ii], ef[ii])[0]
            i1 = nm.where(ef[ii] == facet)[0][0]
            i0 = nm.where(ec[ii] == facet)[0][0]
            ffs.append((facet, i1, i0))

        ffs = nm.array(ffs)

        ie = nm.where(nnn[:, 2] == 1)[0]
        ennn = nnn[ie]
        effs = ffs[ie]
        omit = ie[emask[ennn[:, 0], effs[:, 1]]]

        valid = nm.ones(nnn.shape[0], dtype=nm.bool)
        valid[omit] = False

        cells = nnn[valid]
        facets = ffs[valid]

    return facets, cells, oe, region0, region1
Beispiel #24
0

def set_bc_impl(ts, coors, bc=None, problem=None, **kwargs):
    x = coors[:, 0]
    y = coors[:, 1]
    val = np.sin(x / np.pi) * np.sin(y / np.pi)
    # val = 0*x
    # val = 0.0001*np.ones(x.size)
    return val


# fix_u = EssentialBC('fix_u', omega, {'u.all' : 0.0})
# bc1 = EssentialBC('Gamma_Left', gammaL, {'t.0' : -20.0})
# bc2 = EssentialBC('Gamma_Right', gammaR, {'t.0' : 20.0})

set_bc_fun = Function('set_bc_impl', set_bc_impl)
bc1 = EssentialBC('Gamma_Left', gammaL, {'t.0': set_bc_fun})
bc2 = EssentialBC('Gamma_Right', gammaR, {'t.0': set_bc_fun})

bc3 = EssentialBC('Gamma_Top', gammaT, {'t.0': set_bc_fun})
bc4 = EssentialBC('Gamma_Bottom', gammaB, {'t.0': set_bc_fun})

ls = ScipyDirect({})

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

pb = Problem('Poisson', equations=eqs, nls=nls, ls=ls)
pb.save_regions_as_groups('regions')
Beispiel #25
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 #26
0
# ------------------------------
# | Create bounrady 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 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)
Beispiel #27
0
    def test_epbcs(self):
        from sfepy.discrete import Function, Functions
        from sfepy.discrete.conditions import Conditions, PeriodicBC
        from sfepy.discrete.common.dof_info import expand_nodes_to_equations
        from sfepy.discrete.fem.periodic import match_y_line

        variables = self.variables
        regions = self.problem.domain.regions

        match_y_line = Function('match_y_line', match_y_line)
        pbc = PeriodicBC('pbc', [regions['LeftStrip'], regions['RightStrip']],
                         {'u.[1,0]': 'u.[0,1]'},
                         match='match_y_line')

        functions = Functions([match_y_line])

        epbcs = Conditions([pbc])
        variables.equation_mapping(ebcs=None,
                                   epbcs=epbcs,
                                   ts=None,
                                   functions=functions)

        vec = init_vec(variables)
        variables.apply_ebc(vec)

        var = variables['u']
        var_bcs = epbcs.group_by_variables()['u']
        bc = var_bcs['pbc']
        bc.canonize_dof_names(var.dofs)

        nods0 = var.field.get_dofs_in_region(bc.regions[0])
        nods1 = var.field.get_dofs_in_region(bc.regions[1])

        coors0 = var.field.get_coor(nods0)
        coors1 = var.field.get_coor(nods1)
        i0, i1 = match_y_line(coors0, coors1)

        eq0 = expand_nodes_to_equations(nods0[i0], bc.dofs[0], var.dofs)
        eq1 = expand_nodes_to_equations(nods1[i1], bc.dofs[1], var.dofs)

        ok = True

        _ok = len(nm.setdiff1d(eq0, var.eq_map.master)) == 0
        if not _ok:
            self.report('master equations mismatch! (set(%s) == set(%s))' %
                        (eq0, var.eq_map.master))
        ok = ok and _ok

        _ok = len(nm.setdiff1d(eq1, var.eq_map.slave)) == 0
        if not _ok:
            self.report('slave equations mismatch! (set(%s) == set(%s))' %
                        (eq1, var.eq_map.slave))
        ok = ok and _ok

        off = variables.di.indx['u'].start
        _ok = nm.allclose(vec[off + eq0], vec[off + eq1], atol=1e-14, rtol=0.0)
        if not _ok:
            self.report('periodicity test failed! (%s == %s)' %
                        (vec[off + eq0], vec[off + eq0]))
        ok = ok and _ok

        return ok