Example #1
0
    def from_conf(conf, dpb, apb):

        opts = conf.options
        regions = dpb.domain.regions
        if opts.use_mesh_velocity:
            import tables as pt
            fd = pt.open_file(opts.mesh_velocity_filename, mode='r')
            aux = fd.get_node('/u').read()
            nu = nm.asarray(aux, dtype=nm.float64)
            fd.close()

        else:
            nu = None

        sp_boxes = ffd.read_spline_box_hdf5(opts.ffd_spline_data)
        dsg_vars = ffd.read_dsg_vars_hdf5(opts.ffd_spline_data)
        dsg_vars.renumber_by_boxes(sp_boxes)
        dsg_vars.normalize_null_space_base()
        print dsg_vars.indx.shape
        print dsg_vars.null_space_b.shape

        control_region = regions[opts.control_domain]
        design_region = regions[opts.design_domain]

        from sfepy.discrete.fem.mesh import Mesh
        cmm = Mesh.from_region(control_region, dpb.domain.mesh)
        dmm = Mesh.from_region(design_region, dpb.domain.mesh)
        cmm.write('control.mesh', io='auto')
        dmm.write('design.mesh', io='auto')

        SOFC = ShapeOptimFlowCase
        obj = SOFC(dpb=dpb,
                   apb=apb,
                   sp_boxes=sp_boxes,
                   dsg_vars=dsg_vars,
                   problem_type=opts.problem,
                   objective_function_type=opts.objective_function,
                   var_map=opts.var_map,
                   nu=nu,
                   use_mesh_velocity=opts.use_mesh_velocity,
                   save_dir=opts.save_dir,
                   save_iter_sols=opts.save_iter_sols,
                   save_control_points=opts.save_control_points,
                   save_dsg_vars=opts.save_dsg_vars,
                   test_terms_if_test=opts.test_terms_if_test)

        equations = getattr(
            conf, '_'.join(('equations_sensitivity', opts.problem,
                            opts.objective_function)))

        obj.obj_fun_term = equations['objective']
        obj.sens_terms = equations['sensitivity']

        obj.n_var = dsg_vars.val.shape[0]

        obj.create_evaluables()

        return obj
Example #2
0
    def from_conf(conf, dpb, apb):

        opts = conf.options
        regions = dpb.domain.regions
        if opts.use_mesh_velocity:
            import tables as pt
            fd = pt.open_file( opts.mesh_velocity_filename, mode = 'r' )
            aux = fd.get_node( '/u' ).read()
            nu = nm.asarray( aux, dtype = nm.float64 )
            fd.close()

        else:
            nu = None

        sp_boxes = ffd.read_spline_box_hdf5( opts.ffd_spline_data )
        dsg_vars = ffd.read_dsg_vars_hdf5( opts.ffd_spline_data )
        dsg_vars.renumber_by_boxes( sp_boxes )
        dsg_vars.normalize_null_space_base()
        print dsg_vars.indx.shape
        print dsg_vars.null_space_b.shape

        control_region = regions[opts.control_domain]
        design_region = regions[opts.design_domain]

        from sfepy.discrete.fem.mesh import Mesh
        cmm = Mesh.from_region(control_region, dpb.domain.mesh)
        dmm = Mesh.from_region(design_region, dpb.domain.mesh)
        cmm.write( 'control.mesh', io = 'auto' )
        dmm.write( 'design.mesh', io = 'auto' )

        SOFC = ShapeOptimFlowCase
        obj = SOFC(dpb=dpb, apb=apb,
                   sp_boxes=sp_boxes,
                   dsg_vars=dsg_vars,
                   problem_type=opts.problem,
                   objective_function_type=opts.objective_function,
                   var_map=opts.var_map,
                   nu=nu,
                   use_mesh_velocity=opts.use_mesh_velocity,
                   save_dir=opts.save_dir,
                    save_iter_sols=opts.save_iter_sols,
                   save_control_points=opts.save_control_points,
                   save_dsg_vars=opts.save_dsg_vars,
                   test_terms_if_test=opts.test_terms_if_test)

        equations = getattr( conf, '_'.join( ('equations_sensitivity',
                                              opts.problem,
                                              opts.objective_function) ) )

        obj.obj_fun_term = equations['objective']
        obj.sens_terms = equations['sensitivity']

        obj.n_var = dsg_vars.val.shape[0]

        obj.create_evaluables()

        return obj
Example #3
0
def gen_mesh_from_geom(geo, a=None, verbose=False, refine=False):
    """
    Runs mesh generator - tetgen for 3D or triangle for 2D meshes.

    Parameters
    ----------
    geo : geometry
        geometry description
    a : int, optional
        a maximum area/volume constraint
    verbose : bool, optional
        detailed information
    refine : bool, optional
        refines mesh

    Returns
    -------
    mesh : Mesh instance
        triangular or tetrahedral mesh
    """

    import os.path as op
    import pexpect
    import tempfile
    import shutil

    tmp_dir = tempfile.mkdtemp()
    polyfilename = op.join(tmp_dir, 'meshgen.poly')

    # write geometry to poly file
    geo.to_poly_file(polyfilename)
    meshgen_call = {2: ('triangle', ''), 3: ('tetgen', 'BFENk')}

    params = "-ACp"
    params += "q" if refine else ''
    params += "V" if verbose else "Q"
    params += meshgen_call[geo.dim][1]
    if a is not None:
        params += "a%f" % (a)
    params += " %s" % (polyfilename)

    cmd = "%s %s" % (meshgen_call[geo.dim][0], params)
    if verbose: print "Generating mesh using", cmd

    p=pexpect.run(cmd, timeout=None)
    bname, ext = op.splitext(polyfilename)
    if geo.dim == 2:
        mesh = Mesh.from_file(bname + '.1.node')
    if geo.dim == 3:
        mesh = Mesh.from_file(bname + '.1.vtk')

    shutil.rmtree(tmp_dir)

    return mesh
Example #4
0
    def create_mesh(self, extra_nodes=True):
        """
        Create a mesh from the field region, optionally including the field
        extra nodes.
        """
        mesh = self.domain.mesh

        if self.approx_order != 0:
            conns, mat_ids, descs = [], [], []
            for ig, ap in self.aps.iteritems():
                group = self.domain.groups[ig]
                if extra_nodes:
                    conn = ap.econn
                else:
                    offset = group.shape.n_ep
                    conn = ap.econn[:,:offset]
                conns.append(conn)
                mat_ids.append(mesh.mat_ids[ig])
                descs.append(mesh.descs[ig])

            if extra_nodes:
                coors = self.coors

            else:
                coors = self.coors[:self.n_vertex_dof]

            mesh = Mesh.from_data(self.name, coors, None, conns,
                                  mat_ids, descs)

        return mesh
Example #5
0
    def create_mesh(self, extra_nodes=True):
        """
        Create a mesh from the field region, optionally including the field
        extra nodes.
        """
        mesh = self.domain.mesh

        if self.approx_order != 0:
            if extra_nodes:
                conn = self.econn

            else:
                conn = self.econn[:, :self.gel.n_vertex]

            conns = [conn]
            mat_ids = [mesh.cmesh.cell_groups]
            descs = mesh.descs[:1]

            if extra_nodes:
                coors = self.coors

            else:
                coors = self.coors[:self.n_vertex_dof]

            mesh = Mesh.from_data(self.name, coors, None, conns, mat_ids,
                                  descs)

        return mesh
Example #6
0
def main():
    parser = ArgumentParser(description=__doc__)
    parser.add_argument("--version", action="version", version="%(prog)s 42")
    parser.add_argument("-s", "--scale", type=int, metavar='scale',
                        action="store", dest="scale",
                        default=2, help=helps['scale'])
    parser.add_argument("-r", "--repeat", type=str, metavar='nx,ny[,nz]',
                        action=ParseRepeat, dest="repeat",
                        default=None, help=helps['repeat'])
    parser.add_argument("-e", "--eps", type=float, metavar='eps',
                        action="store", dest="eps",
                        default=1e-8, help=helps['eps'])
    parser.add_argument('filename_in')
    parser.add_argument('filename_out')
    options = parser.parse_args()

    filename_in = options.filename_in
    filename_out = options.filename_out

    output = Output('tpm:')
    output('scale:', options.scale)
    output('repeat:', options.repeat)
    output('eps:', options.eps)

    mesh_in = Mesh.from_file(filename_in)
    mesh_out = gen_tiled_mesh(mesh_in, options.repeat, 1./options.scale,
                              options.eps)
    mesh_out.write(filename_out, io='auto')
    output('done.')
Example #7
0
def load_state_1D_vtk(name):
    """Load one VTK file containing state in time

    Parameters
    ----------
    name : str

    Returns
    -------
    coors : ndarray
    u : ndarray
    """

    from sfepy.discrete.fem.meshio import MeshioLibIO
    io = MeshioLibIO(name)
    coors = io.read(Mesh()).coors[:, 0, None]
    data = io.read_data(step=0)
    var_name = head([k for k in data.keys() if "_modal" in k])[:-1]
    if var_name is None:
        print("File {} does not contain modal data.".format(name))
        return
    porder = len([k for k in data.keys() if var_name in k])


    u = nm.zeros((porder, coors.shape[0] - 1, 1, 1))
    for ii in range(porder):
        u[ii, :, 0, 0] = data[var_name+'{}'.format(ii)].data

    return coors, u
def main():
    parser = OptionParser(usage=usage, version="%prog 42")
    parser.add_option("-s", "--scale", type=int, metavar='scale',
                      action="store", dest="scale",
                      default=2, help=help['scale'])
    parser.add_option("-r", "--repeat", type='str', metavar='nx,ny[,nz]',
                      action="callback", dest="repeat",
                      callback=parse_repeat, default=None, help=help['repeat'])
    parser.add_option("-e", "--eps", type=float, metavar='eps',
                      action="store", dest="eps",
                      default=1e-8, help=help['eps'])
    (options, args) = parser.parse_args()

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

    output = Output('tpm:')
    output('scale:', options.scale)
    output('repeat:', options.repeat)
    output('eps:', options.eps)

    mesh_in = Mesh.from_file(filename_in)
    mesh_out = gen_tiled_mesh(mesh_in, options.repeat, 1./options.scale,
                              options.eps)
    mesh_out.write(filename_out, io='auto')
    output('done.')
Example #9
0
    def create_mesh(self, extra_nodes=True):
        """
        Create a mesh from the field region, optionally including the field
        extra nodes.
        """
        mesh = self.domain.mesh

        if self.approx_order != 0:
            if extra_nodes:
                conn = self.econn

            else:
                conn = self.econn[:, :self.gel.n_vertex]

            conns = [conn]
            mat_ids = [mesh.cmesh.cell_groups]
            descs = mesh.descs[:1]

            if extra_nodes:
                coors = self.coors

            else:
                coors = self.coors[:self.n_vertex_dof]

            mesh = Mesh.from_data(self.name, coors, None, conns,
                                  mat_ids, descs)

        return mesh
Example #10
0
    def create_mesh(self, extra_nodes=True):
        """
        Create a mesh from the field region, optionally including the field
        extra nodes.
        """
        mesh = self.domain.mesh

        if self.approx_order != 0:
            conns, mat_ids, descs = [], [], []
            for ig, ap in self.aps.iteritems():
                group = self.domain.groups[ig]
                if extra_nodes:
                    conn = ap.econn
                else:
                    offset = group.shape.n_ep
                    conn = ap.econn[:,:offset]
                conns.append(conn)
                mat_ids.append(mesh.mat_ids[ig])
                descs.append(mesh.descs[ig])

            if extra_nodes:
                coors = self.coors

            else:
                coors = self.coors[:self.n_vertex_dof]

            mesh = Mesh.from_data(self.name, coors, None, conns,
                                  mat_ids, descs)

        return mesh
Example #11
0
    def linearize(self, dofs, min_level=0, max_level=1, eps=1e-4):
        """
        Linearize the solution for post-processing.

        Parameters
        ----------
        dofs : array, shape (n_nod, n_component)
            The array of DOFs reshaped so that each column corresponds
            to one component.
        min_level : int
            The minimum required level of mesh refinement.
        max_level : int
            The maximum level of mesh refinement.
        eps : float
            The relative tolerance parameter of mesh adaptivity.

        Returns
        -------
        mesh : Mesh instance
            The adapted, nonconforming, mesh.
        vdofs : array
            The DOFs defined in vertices of `mesh`.
        levels : array of ints
            The refinement level used for each element group.
        """
        assert_(dofs.ndim == 2)

        n_nod, dpn = dofs.shape

        assert_(n_nod == self.n_nod)
        assert_(dpn == self.shape[0])

        vertex_coors = self.coors[:self.n_vertex_dof, :]

        ap = self.ap

        ps = ap.interp.poly_spaces['v']
        gps = ap.interp.gel.interp.poly_spaces['v']

        vertex_conn = ap.econn[:, :self.gel.n_vertex]

        eval_dofs = get_eval_dofs(dofs, ap.econn, ps, ori=ap.ori)
        eval_coors = get_eval_coors(vertex_coors, vertex_conn, gps)

        (level, coors, conn, vdofs,
         mat_ids) = create_output(eval_dofs,
                                  eval_coors,
                                  vertex_conn.shape[0],
                                  ps,
                                  min_level=min_level,
                                  max_level=max_level,
                                  eps=eps)

        mesh = Mesh.from_data('linearized_mesh', coors, None, [conn],
                              [mat_ids], self.domain.mesh.descs)

        return mesh, vdofs, level
Example #12
0
def gen_block_mesh(dims, shape, centre, mat_id=0, name='block',
                   coors=None, verbose=True):
    """
    Generate a 2D or 3D block mesh. The dimension is determined by the
    lenght of the shape argument.

    Parameters
    ----------
    dims : array of 2 or 3 floats
        Dimensions of the block.
    shape : array of 2 or 3 ints
        Shape (counts of nodes in x, y, z) of the block mesh.
    centre : array of 2 or 3 floats
        Centre of the block.
    mat_id : int, optional
        The material id of all elements.
    name : string
        Mesh name.
    verbose : bool
        If True, show progress of the mesh generation.

    Returns
    -------
    mesh : Mesh instance
    """
    dims = nm.asarray(dims, dtype=nm.float64)
    shape = nm.asarray(shape, dtype=nm.int32)
    centre = nm.asarray(centre, dtype=nm.float64)

    dim = shape.shape[0]

    centre = centre[:dim]
    dims = dims[:dim]

    n_nod = nm.prod(shape)
    output('generating %d vertices...' % n_nod, verbose=verbose)

    x0 = centre - 0.5 * dims
    dd = dims / (shape - 1)

    ngrid = nm.mgrid[[slice(ii) for ii in shape]]
    ngrid.shape = (dim, n_nod)

    coors = x0 + ngrid.T * dd
    output('...done', verbose=verbose)

    n_el = nm.prod(shape - 1)
    output('generating %d cells...' % n_el, verbose=verbose)

    mat_ids = nm.empty((n_el,), dtype=nm.int32)
    mat_ids.fill(mat_id)

    conn, desc = get_tensor_product_conn(shape)
    output('...done', verbose=verbose)

    mesh = Mesh.from_data(name, coors, None, [conn], [mat_ids], [desc])
    return mesh
Example #13
0
def gen_block_mesh(dims, shape, centre, mat_id=0, name='block',
                   coors=None, verbose=True):
    """
    Generate a 2D or 3D block mesh. The dimension is determined by the
    lenght of the shape argument.

    Parameters
    ----------
    dims : array of 2 or 3 floats
        Dimensions of the block.
    shape : array of 2 or 3 ints
        Shape (counts of nodes in x, y, z) of the block mesh.
    centre : array of 2 or 3 floats
        Centre of the block.
    mat_id : int, optional
        The material id of all elements.
    name : string
        Mesh name.
    verbose : bool
        If True, show progress of the mesh generation.

    Returns
    -------
    mesh : Mesh instance
    """
    dims = nm.asarray(dims, dtype=nm.float64)
    shape = nm.asarray(shape, dtype=nm.int32)
    centre = nm.asarray(centre, dtype=nm.float64)

    dim = shape.shape[0]

    centre = centre[:dim]
    dims = dims[:dim]

    n_nod = nm.prod(shape)
    output('generating %d vertices...' % n_nod, verbose=verbose)

    x0 = centre - 0.5 * dims
    dd = dims / (shape - 1)

    ngrid = nm.mgrid[[slice(ii) for ii in shape]]
    ngrid.shape = (dim, n_nod)

    coors = x0 + ngrid.T * dd
    output('...done', verbose=verbose)

    n_el = nm.prod(shape - 1)
    output('generating %d cells...' % n_el, verbose=verbose)

    mat_ids = nm.empty((n_el,), dtype=nm.int32)
    mat_ids.fill(mat_id)

    conn, desc = get_tensor_product_conn(shape)
    output('...done', verbose=verbose)

    mesh = Mesh.from_data(name, coors, None, [conn], [mat_ids], [desc])
    return mesh
Example #14
0
    def linearize(self, dofs, min_level=0, max_level=1, eps=1e-4):
        """
        Linearize the solution for post-processing.

        Parameters
        ----------
        dofs : array, shape (n_nod, n_component)
            The array of DOFs reshaped so that each column corresponds
            to one component.
        min_level : int
            The minimum required level of mesh refinement.
        max_level : int
            The maximum level of mesh refinement.
        eps : float
            The relative tolerance parameter of mesh adaptivity.

        Returns
        -------
        mesh : Mesh instance
            The adapted, nonconforming, mesh.
        vdofs : array
            The DOFs defined in vertices of `mesh`.
        levels : array of ints
            The refinement level used for each element group.
        """
        assert_(dofs.ndim == 2)

        n_nod, dpn = dofs.shape

        assert_(n_nod == self.n_nod)
        assert_(dpn == self.shape[0])

        vertex_coors = self.coors[:self.n_vertex_dof, :]

        ap = self.ap

        ps = ap.interp.poly_spaces['v']
        gps = ap.interp.gel.interp.poly_spaces['v']

        vertex_conn = ap.econn[:, :self.gel.n_vertex]

        eval_dofs = get_eval_dofs(dofs, ap.econn, ps, ori=ap.ori)
        eval_coors = get_eval_coors(vertex_coors, vertex_conn, gps)

        (level, coors, conn,
         vdofs, mat_ids) = create_output(eval_dofs, eval_coors,
                                         vertex_conn.shape[0], ps,
                                         min_level=min_level,
                                         max_level=max_level, eps=eps)

        mesh = Mesh.from_data('linearized_mesh', coors, None, [conn], [mat_ids],
                              self.domain.mesh.descs)

        return mesh, vdofs, level
Example #15
0
    def test_mesh_expand(self):
        import numpy as nm
        from sfepy.mesh.mesh_tools import expand2d
        from sfepy.discrete.fem.mesh import Mesh
        from sfepy import data_dir

        mesh2d = Mesh.from_file(data_dir + '/meshes/2d/square_quad.mesh')
        mesh3d_ref = Mesh.from_file(data_dir +\
                                    '/meshes/3d/cube_medium_hexa.mesh')
        mesh3d_gen = expand2d(mesh2d, 0.1, 10)
        mesh3d_gen.coors[:,2] += -0.5

        d0 = nm.sort(nm.linalg.norm(mesh3d_ref.coors, axis=1))
        d1 = nm.sort(nm.linalg.norm(mesh3d_gen.coors, axis=1))
        if nm.linalg.norm(d0 - d1) < 1e-6:
            return True

        else:
            return False

        return True
Example #16
0
    def test_mesh_expand(self):
        import numpy as nm
        from sfepy.mesh.mesh_tools import expand2d
        from sfepy.discrete.fem.mesh import Mesh
        from sfepy import data_dir

        mesh2d = Mesh.from_file(data_dir + '/meshes/2d/square_quad.mesh')
        mesh3d_ref = Mesh.from_file(data_dir +\
                                    '/meshes/3d/cube_medium_hexa.mesh')
        mesh3d_gen = expand2d(mesh2d, 0.1, 10)
        mesh3d_gen.coors[:, 2] += -0.5

        d0 = nm.sort(nm.linalg.norm(mesh3d_ref.coors, axis=1))
        d1 = nm.sort(nm.linalg.norm(mesh3d_gen.coors, axis=1))
        if nm.linalg.norm(d0 - d1) < 1e-6:
            return True

        else:
            return False

        return True
Example #17
0
def main():
    parser = ArgumentParser(description=__doc__)
    parser.add_argument("--version", action="version", version="%(prog)s 42")
    parser.add_argument("-s",
                        "--scale",
                        type=int,
                        metavar='scale',
                        action="store",
                        dest="scale",
                        default=2,
                        help=help['scale'])
    parser.add_argument("-r",
                        "--repeat",
                        type=str,
                        metavar='nx,ny[,nz]',
                        action=ParseRepeat,
                        dest="repeat",
                        default=None,
                        help=help['repeat'])
    parser.add_argument("-e",
                        "--eps",
                        type=float,
                        metavar='eps',
                        action="store",
                        dest="eps",
                        default=1e-8,
                        help=help['eps'])
    parser.add_argument('filename_in')
    parser.add_argument('filename_out')
    options = parser.parse_args()

    filename_in = options.filename_in
    filename_out = options.filename_out

    output = Output('tpm:')
    output('scale:', options.scale)
    output('repeat:', options.repeat)
    output('eps:', options.eps)

    mesh_in = Mesh.from_file(filename_in)
    mesh_out = gen_tiled_mesh(mesh_in, options.repeat, 1. / options.scale,
                              options.eps)
    mesh_out.write(filename_out, io='auto')
    output('done.')
Example #18
0
    def test_mesh_smoothing(self):
        from sfepy.mesh.mesh_tools import smooth_mesh
        from sfepy.discrete.fem.mesh import Mesh
        from sfepy import data_dir

        mesh = Mesh.from_file(data_dir + '/meshes/3d/cylinder.vtk')
        vol0 = get_volume(mesh.conns[0], mesh.coors)
        mesh.coors = smooth_mesh(mesh, n_iter=10)
        vol1 = get_volume(mesh.conns[0], mesh.coors)
        filename = op.join(self.options.out_dir, 'smoothed_cylinder.vtk')
        mesh.write(filename)
        frac = vol1 / vol0

        if (frac < 0.967) and (frac > 0.966):
            self.report('mesh smoothed')
            return True

        else:
            self.report('mesh smoothed, volume mismatch!')
            return False
Example #19
0
    def test_mesh_smoothing(self):
        from sfepy.mesh.mesh_tools import smooth_mesh
        from sfepy.discrete.fem.mesh import Mesh
        from sfepy import data_dir

        mesh = Mesh.from_file(data_dir + '/meshes/3d/cylinder.vtk')
        vol0 = get_volume(mesh.conns[0], mesh.coors)
        mesh.coors = smooth_mesh(mesh, n_iter=10)
        vol1 = get_volume(mesh.conns[0], mesh.coors)
        filename = op.join(self.options.out_dir, 'smoothed_cylinder.vtk')
        mesh.write(filename)
        frac = vol1 / vol0

        if (frac < 0.967) and (frac > 0.966):
            self.report('mesh smoothed')
            return True

        else:
            self.report('mesh smoothed, volume mismatch!')
            return False
Example #20
0
    def from_conf(conf, init_fields=True, init_equations=True,
                  init_solvers=True):
        if conf.options.get('absolute_mesh_path', False):
            conf_dir = None
        else:
            conf_dir = op.dirname(conf.funmod.__file__)

        functions = Functions.from_conf(conf.functions)

        if conf.get('filename_mesh') is not None:
            from sfepy.discrete.fem.domain import FEDomain

            mesh = Mesh.from_file(conf.filename_mesh, prefix_dir=conf_dir)
            domain = FEDomain(mesh.name, mesh)
            if conf.options.get('ulf', False):
                domain.mesh.coors_act = domain.mesh.coors.copy()

        elif conf.get('filename_domain') is not None:
            from sfepy.discrete.iga.domain import IGDomain
            domain = IGDomain.from_file(conf.filename_domain)

        else:
            raise ValueError('missing filename_mesh or filename_domain!')

        obj = Problem('problem_from_conf', conf=conf, functions=functions,
                      domain=domain, auto_conf=False, auto_solvers=False)

        obj.set_regions(conf.regions, obj.functions)

        obj.clear_equations()

        if init_fields:
            obj.set_fields(conf.fields)

            if init_equations:
                obj.set_equations(conf.equations, user={'ts' : obj.ts})

        if init_solvers:
            obj.set_solvers(conf.solvers, conf.options)

        return obj
Example #21
0
    def from_conf(conf, init_fields=True, init_equations=True,
                  init_solvers=True):
        if conf.options.get('absolute_mesh_path', False):
            conf_dir = None
        else:
            conf_dir = op.dirname(conf.funmod.__file__)

        functions = Functions.from_conf(conf.functions)

        if conf.get('filename_mesh') is not None:
            from sfepy.discrete.fem.domain import FEDomain

            mesh = Mesh.from_file(conf.filename_mesh, prefix_dir=conf_dir)
            domain = FEDomain(mesh.name, mesh)
            if conf.options.get('ulf', False):
                domain.mesh.coors_act = domain.mesh.coors.copy()

        elif conf.get('filename_domain') is not None:
            from sfepy.discrete.iga.domain import IGDomain
            domain = IGDomain.from_file(conf.filename_domain)

        else:
            raise ValueError('missing filename_mesh or filename_domain!')

        obj = Problem('problem_from_conf', conf=conf, functions=functions,
                      domain=domain, auto_conf=False, auto_solvers=False)

        obj.set_regions(conf.regions, obj.functions)

        obj.clear_equations()

        if init_fields:
            obj.set_fields(conf.fields)

            if init_equations:
                obj.set_equations(conf.equations, user={'ts' : obj.ts})

        if init_solvers:
            obj.set_solvers(conf.solvers, conf.options)

        return obj
Example #22
0
    def create_mesh_from_control_points(self):
        offset = 0
        dim = self.spbs[0].cxyz.shape[1]
        coors = nm.empty((0, dim), dtype=nm.float64)
        conns = []
        mat_ids = []
        descs = []
        for ib, spb in enumerate(self.spbs):
            n_nod = spb.cxyz.shape[0]
            coors = nm.concatenate((coors, spb.cxyz), 0)
            descs.append('3_2')

            conn = []
            for ij in xrange(spb.cpi.shape[1]):
                for ik in xrange(spb.cpi.shape[2]):
                    inx = spb.cpi[:, ij, ik]
                    row = [[p1, p2] for p1, p2 in zip(inx[:-1], inx[1:])]
                    conn.extend(row)
            for ij in xrange(spb.cpi.shape[0]):
                for ik in xrange(spb.cpi.shape[2]):
                    inx = spb.cpi[ij, :, ik]
                    row = [[p1, p2] for p1, p2 in zip(inx[:-1], inx[1:])]
                    conn.extend(row)
            for ij in xrange(spb.cpi.shape[0]):
                for ik in xrange(spb.cpi.shape[1]):
                    inx = spb.cpi[ij, ik, :]
                    row = [[p1, p2] for p1, p2 in zip(inx[:-1], inx[1:])]
                    conn.extend(row)

            aux = nm.empty(len(conn), dtype=nm.int32)
            aux.fill(ib)
            mat_ids.append(aux)

            conns.append(offset + nm.array(conn, dtype=nm.int32))
            offset += n_nod

        mesh = Mesh.from_data('control_points', coors, None, conns, mat_ids,
                              descs)
        return mesh
Example #23
0
    def create_mesh_from_control_points( self ):
        offset = 0
        dim = self.spbs[0].cxyz.shape[1]
        coors = nm.empty((0, dim), dtype=nm.float64)
        conns = []
        mat_ids = []
        descs = []
        for ib, spb in enumerate( self.spbs ):
            n_nod = spb.cxyz.shape[0]
            coors = nm.concatenate( (coors, spb.cxyz), 0 )
            descs.append( '3_2' )

            conn = []
            for ij in range( spb.cpi.shape[1] ):
                for ik in range( spb.cpi.shape[2] ):
                    inx = spb.cpi[:,ij,ik]
                    row = [[p1, p2] for p1, p2 in zip( inx[:-1], inx[1:] )]
                    conn.extend( row )
            for ij in range( spb.cpi.shape[0] ):
                for ik in range( spb.cpi.shape[2] ):
                    inx = spb.cpi[ij,:,ik]
                    row = [[p1, p2] for p1, p2 in zip( inx[:-1], inx[1:] )]
                    conn.extend( row )
            for ij in range( spb.cpi.shape[0] ):
                for ik in range( spb.cpi.shape[1] ):
                    inx = spb.cpi[ij,ik,:]
                    row = [[p1, p2] for p1, p2 in zip( inx[:-1], inx[1:] )]
                    conn.extend( row )

            aux = nm.empty(len(conn), dtype=nm.int32)
            aux.fill(ib)
            mat_ids.append(aux)

            conns.append( offset + nm.array( conn, dtype = nm.int32 ) )
            offset += n_nod

        mesh = Mesh.from_data('control_points', coors, None, conns,
                              mat_ids, descs)
        return mesh
Example #24
0
    def from_conf(conf, init_fields=True, init_equations=True, init_solvers=True):
        if conf.options.get("absolute_mesh_path", False):
            conf_dir = None
        else:
            conf_dir = op.dirname(conf.funmod.__file__)

        functions = Functions.from_conf(conf.functions)

        mesh = Mesh.from_file(conf.filename_mesh, prefix_dir=conf_dir)

        trans_mtx = conf.options.get("mesh_coors_transform", None)

        if trans_mtx is not None:
            mesh.transform_coors(trans_mtx)

        domain = Domain(mesh.name, mesh)
        if conf.options.get("ulf", False):
            domain.mesh.coors_act = domain.mesh.coors.copy()

        obj = Problem(
            "problem_from_conf", conf=conf, functions=functions, domain=domain, auto_conf=False, auto_solvers=False
        )

        obj.set_regions(conf.regions, obj.functions)

        obj.clear_equations()

        if init_fields:
            obj.set_fields(conf.fields)

            if init_equations:
                obj.set_equations(conf.equations, user={"ts": obj.ts})

        if init_solvers:
            obj.set_solvers(conf.solvers, conf.options)

        return obj
Example #25
0
def define(grid0=100, filename_mesh=None):
    eps0 = 0.01 / grid0

    if filename_mesh is None:
        filename_mesh = osp.join(data_dir, 'piezo_mesh_micro_dfc.vtk')

    mesh = Mesh.from_file(filename_mesh)
    n_conduct = len(nm.unique(mesh.cmesh.cell_groups)) - 2

    sym_eye = 'nm.array([1,1,0])' if mesh.dim == 2 else\
        'nm.array([1,1,1,0,0,0])'

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

    regions.update({
        'Y': 'all',
        # matrix
        'Ym': 'cells of group 1',
        'Ym_left': ('r.Ym *v r.Left', 'vertex'),
        'Ym_right': ('r.Ym *v r.Right', 'vertex'),
        'Ym_bottom': ('r.Ym *v r.Bottom', 'vertex'),
        'Ym_top': ('r.Ym *v r.Top', 'vertex'),
        'Ym_far': ('r.Ym *v r.Far', 'vertex'),
        'Ym_near': ('r.Ym *v r.Near', 'vertex'),
        'Gamma_mc': ('r.Ym *v r.Yc', 'facet', 'Ym'),
        # channel / inclusion
        'Yc': 'cells of group 2',
        'Yc0': ('r.Yc -v r.Gamma_cm', 'vertex'),
        'Gamma_cm': ('r.Ym *v r.Yc', 'facet', 'Yc'),
    })

    print('number of cnonductors: %d' % n_conduct)
    regions.update({
        'Yms': ('r.Ym +v r.Ys', 'cell'),
        'Yms_left': ('r.Yms *v r.Left', 'vertex'),
        'Yms_right': ('r.Yms *v r.Right', 'vertex'),
        'Yms_bottom': ('r.Yms *v r.Bottom', 'vertex'),
        'Yms_top': ('r.Yms *v r.Top', 'vertex'),
        'Yms_far': ('r.Yms *v r.Far', 'vertex'),
        'Yms_near': ('r.Yms *v r.Near', 'vertex'),
        'Gamma_ms': ('r.Ym *v r.Ys', 'facet', 'Ym'),
        'Gamma_msc': ('r.Yms *v r.Yc', 'facet', 'Yms'),
        'Ys': (' +v '.join(['r.Ys%d' % k for k in range(n_conduct)]), 'cell'),
    })

    options = {
        'coefs_filename': 'coefs_poropiezo_%d' % (grid0),
        'volume': {
            'variables': ['svar'],
            'expression': 'd_volume.i2.Y(svar)',
        },
        'coefs': 'coefs',
        'requirements': 'requirements',
        'output_dir': osp.join(data_dir, 'results'),
        'ls': 'ls',
        'file_per_var': True,
        'absolute_mesh_path': True,
        'multiprocessing': False,
        'recovery_hook': recovery_micro_dfc,
    }

    fields = {
        'displacement': ('real', 'vector', 'Yms', 1),
        'potential': ('real', 'scalar', 'Ym', 1),
        'sfield': ('real', 'scalar', 'Y', 1),
    }

    variables = {
        # displacement
        'u': ('unknown field', 'displacement'),
        'v': ('test field', 'displacement', 'u'),
        'Pi_u': ('parameter field', 'displacement', 'u'),
        'U1': ('parameter field', 'displacement', '(set-to-None)'),
        'U2': ('parameter field', 'displacement', '(set-to-None)'),
        # potential
        'r': ('unknown field', 'potential'),
        's': ('test field', 'potential', 'r'),
        'Pi_r': ('parameter field', 'potential', 'r'),
        'R1': ('parameter field', 'potential', '(set-to-None)'),
        'R2': ('parameter field', 'potential', '(set-to-None)'),
        # aux variable
        'svar': ('parameter field', 'sfield', '(set-to-None)'),
    }

    epbcs, periodic = get_periodic_bc([('u', 'Yms'), ('r', 'Ym')])

    mat_g_sc, mat_d_sc = eps0, eps0**2
    # BaTiO3 - Miara, Rohan, ... doi: 10.1016/j.jmps.2005.05.006
    materials = {
        'matrix': ({
            'D': {
                'Ym':
                nm.array([[1.504, 0.656, 0.659, 0, 0, 0],
                          [0.656, 1.504, 0.659, 0, 0, 0],
                          [0.659, 0.659, 1.455, 0, 0, 0],
                          [0, 0, 0, 0.424, 0, 0], [0, 0, 0, 0, 0.439, 0],
                          [0, 0, 0, 0, 0, 0.439]]) * 1e11,
            }
        }, ),
        'piezo': ({
            'g':
            nm.array([[0, 0, 0, 0, 11.404, 0], [0, 0, 0, 0, 0, 11.404],
                      [-4.322, -4.322, 17.360, 0, 0, 0]]) / mat_g_sc,
            'd':
            nm.array([[1.284, 0, 0], [0, 1.284, 0], [0, 0, 1.505]]) * 1e-8 /
            mat_d_sc,
        }, ),
        'fluid': ({
            'gamma': 1.0 / 2.15e9
        }, ),
    }

    functions = {
        'match_x_plane': (per.match_x_plane, ),
        'match_y_plane': (per.match_y_plane, ),
        'match_z_plane': (per.match_z_plane, ),
    }

    ebcs = {
        'fixed_u': ('Corners', {
            'u.all': 0.0
        }),
        'fixed_r': ('Gamma_ms', {
            'r.all': 0.0
        }),
    }

    integrals = {
        'i2': 2,
        'i5': 5,
    }

    solvers = {
        'ls': ('ls.scipy_direct', {}),
        'ns_em6': ('nls.newton', {
            'i_max': 1,
            'eps_a': 1e-6,
            'eps_r': 1e-6,
            'problem': 'nonlinear'
        }),
        'ns_em3': ('nls.newton', {
            'i_max': 1,
            'eps_a': 1e-3,
            'eps_r': 1e-6,
            'problem': 'nonlinear'
        }),
    }

    coefs = {
        # homogenized elasticity, see eq. (46)_1
        'A': {
            'requires': ['c.A1', 'c.A2'],
            'expression': 'c.A1 + c.A2',
            'class': cb.CoefEval,
        },
        'A1': {
            'status':
            'auxiliary',
            'requires': ['pis_u', 'corrs_rs'],
            'expression':
            'dw_lin_elastic.i2.Yms(matrix.D, U1, U2)',
            'set_variables': [('U1', ('corrs_rs', 'pis_u'), 'u'),
                              ('U2', ('corrs_rs', 'pis_u'), 'u')],
            'class':
            cb.CoefSymSym,
        },
        'A2': {
            'status': 'auxiliary',
            'requires': ['corrs_rs'],
            'expression': 'dw_diffusion.i2.Ym(piezo.d, R1, R2)',
            'set_variables': [('R1', 'corrs_rs', 'r'),
                              ('R2', 'corrs_rs', 'r')],
            'class': cb.CoefSymSym,
        },
        # homogenized Biot coefficient, see eq. (46)_2
        'B': {
            'requires': ['c.Phi', 'c.B1', 'c.B2'],
            'expression': 'c.B1 - c.B2 + c.Phi * %s' % sym_eye,
            'class': cb.CoefEval,
        },
        'B1': {
            'status': 'auxiliary',
            'requires': ['pis_u', 'corrs_p'],
            'expression': 'dw_lin_elastic.i2.Yms(matrix.D, U1, U2)',
            'set_variables': [('U1', 'corrs_p', 'u'), ('U2', 'pis_u', 'u')],
            'class': cb.CoefSym,
        },
        'B2': {
            'status': 'auxiliary',
            'requires': ['pis_u', 'corrs_p'],
            'expression': 'dw_piezo_coupling.i2.Ym(piezo.g, U1, R1)',
            'set_variables': [('R1', 'corrs_p', 'r'), ('U1', 'pis_u', 'u')],
            'class': cb.CoefSym,
        },
        # homogenized compressibility coefficient, see eq. (46)_6
        'M': {
            'requires': ['c.Phi', 'c.N'],
            'expression': 'c.N + c.Phi * %e' % materials['fluid'][0]['gamma'],
            'class': cb.CoefEval,
        },
        'N': {
            'status': 'auxiliary',
            'requires': ['corrs_p'],
            'expression': 'dw_surface_ltr.i2.Gamma_msc(U1)',
            'set_variables': [('U1', 'corrs_p', 'u')],
            'class': cb.CoefOne,
        },
        'Phi': {
            'requires': ['c.vol'],
            'expression': 'c.vol["fraction_Yc"]',
            'class': cb.CoefEval,
        },
        # volume fractions of Ym, Yc, Ys1, Ys2, ...
        'vol': {
            'regions': ['Ym', 'Yc'] + ['Ys%d' % k for k in range(n_conduct)],
            'expression': 'd_volume.i2.%s(svar)',
            'class': cb.VolumeFractions,
        },
        'eps0': {
            'requires': [],
            'expression': '%e' % eps0,
            'class': cb.CoefEval,
        },
        'filenames': {},
    }

    requirements = {
        'pis_u': {
            'variables': ['u'],
            'class': cb.ShapeDimDim,
        },
        'pis_r': {
            'variables': ['r'],
            'class': cb.ShapeDim,
        },
        # local subproblem defined by eq. (41)
        'corrs_rs': {
            'requires': ['pis_u'],
            'ebcs': ['fixed_u', 'fixed_r'],
            'epbcs': periodic['per_u'] + periodic['per_r'],
            'is_linear': True,
            'equations': {
                'eq1':
                """dw_lin_elastic.i2.Yms(matrix.D, v, u)
                     - dw_piezo_coupling.i2.Ym(piezo.g, v, r)
                   = - dw_lin_elastic.i2.Yms(matrix.D, v, Pi_u)""",
                'eq2':
                """
                     - dw_piezo_coupling.i2.Ym(piezo.g, u, s)
                     - dw_diffusion.i2.Ym(piezo.d, s, r)
                     = dw_piezo_coupling.i2.Ym(piezo.g, Pi_u, s)""",
            },
            'set_variables': [('Pi_u', 'pis_u', 'u')],
            'class': cb.CorrDimDim,
            'save_name': 'corrs_rs_%d' % grid0,
            'dump_variables': ['u', 'r'],
            'solvers': {
                'ls': 'ls',
                'nls': 'ns_em3'
            },
        },
        # local subproblem defined by eq. (42)
        'corrs_p': {
            'requires': [],
            'ebcs': ['fixed_u', 'fixed_r'],
            'epbcs': periodic['per_u'] + periodic['per_r'],
            'is_linear': True,
            'equations': {
                'eq1':
                """dw_lin_elastic.i2.Yms(matrix.D, v, u)
                     - dw_piezo_coupling.i2.Ym(piezo.g, v, r)
                     = dw_surface_ltr.i2.Gamma_msc(v)""",
                'eq2':
                """
                     - dw_piezo_coupling.i2.Ym(piezo.g, u, s)
                     - dw_diffusion.i2.Ym(piezo.d, s, r)
                     = 0"""
            },
            'class': cb.CorrOne,
            'save_name': 'corrs_p_%d' % grid0,
            'dump_variables': ['u', 'r'],
            'solvers': {
                'ls': 'ls',
                'nls': 'ns_em6'
            },
        },
        # local subproblem defined by eq. (43)
        'corrs_rho': {
            'requires': [],
            'ebcs': ['fixed_u', 'fixed_r'],
            'epbcs': periodic['per_u'] + periodic['per_r'],
            'is_linear': True,
            'equations': {
                'eq1':
                """dw_lin_elastic.i2.Yms(matrix.D, v, u)
                        - dw_piezo_coupling.i2.Ym(piezo.g, v, r)
                        = 0""",
                'eq2':
                """
                        - dw_piezo_coupling.i2.Ym(piezo.g, u, s)
                        - dw_diffusion.i2.Ym(piezo.d, s, r)
                        =
                        - dw_surface_integrate.i2.Gamma_mc(s)"""
            },
            'class': cb.CorrOne,
            'save_name': 'corrs_p_%d' % grid0,
            'dump_variables': ['u', 'r'],
            'solvers': {
                'ls': 'ls',
                'nls': 'ns_em6'
            },
        },
    }

    for k in range(n_conduct):
        sk = '%d' % k
        regions.update({
            'Ys' + sk: 'cells of group %d' % (3 + k),
            'Gamma_s' + sk: ('r.Ym *v r.Ys' + sk, 'facet', 'Ym'),
        })

        materials['matrix'][0]['D'].update({
            'Ys' + sk:
            stiffness_from_youngpoisson(3, 200e9, 0.25),
        })

        ebcs.update({
            'fixed_r1_k_' + sk: ('Gamma_s' + sk, {
                'r.0': 1.0
            }),
            'fixed_r0_k_' + sk: ('Gamma_s' + sk, {
                'r.0': 0.0
            }),
        })

        fixed_r0_k = [
            'fixed_r0_k_%d' % ii for ii in range(n_conduct) if not ii == k
        ]
        # local subproblems defined for conductors, see eq. (44)
        requirements.update({
            'corrs_k' + sk: {
                'requires': ['pis_r'],
                'ebcs': ['fixed_u', 'fixed_r1_k_' + sk] + fixed_r0_k,
                'epbcs': periodic['per_u'] + periodic['per_r'],
                'is_linear': True,
                'equations': {
                    'eq1':
                    """dw_lin_elastic.i2.Yms(matrix.D, v, u)
                            - dw_piezo_coupling.i2.Ym(piezo.g, v, r)
                            = 0""",
                    'eq2':
                    """
                            - dw_piezo_coupling.i2.Ym(piezo.g, u, s)
                            - dw_diffusion.i2.Ym(piezo.d, s, r)
                            = 0"""
                },
                'class': cb.CorrOne,
                'save_name': 'corrs_k' + sk + '_%d' % grid0,
                'dump_variables': ['u', 'r'],
                'solvers': {
                    'ls': 'ls',
                    'nls': 'ns_em6'
                },
            },
        })

        coefs.update({
            # homogenized coefficient (46)_3
            'H' + sk: {
                'requires': ['c.H1_' + sk, 'c.H2_' + sk],
                'expression': 'c.H1_%s - c.H2_%s' % (sk, sk),
                'class': cb.CoefEval,
            },
            'H1_' + sk: {
                'status':
                'auxiliary',
                'requires': ['pis_u', 'corrs_k' + sk],
                'expression':
                'dw_lin_elastic.i2.Yms(matrix.D, U1, U2)',
                'set_variables': [('U1', 'corrs_k' + sk, 'u'),
                                  ('U2', 'pis_u', 'u')],
                'class':
                cb.CoefSym,
            },
            'H2_' + sk: {
                'status':
                'auxiliary',
                'requires': ['pis_u', 'corrs_k' + sk],
                'expression':
                'dw_piezo_coupling.i2.Ym(piezo.g, U1, R1)',
                'set_variables': [('R1', 'corrs_k' + sk, 'r'),
                                  ('U1', 'pis_u', 'u')],
                'class':
                cb.CoefSym,
            },
            # homogenized coefficient (46)_7
            'Z' + sk: {
                'requires': ['corrs_k' + sk],
                'expression': 'dw_surface_ltr.i2.Gamma_msc(U1)',
                'set_variables': [('U1', 'corrs_k' + sk, 'u')],
                'class': cb.CoefOne,
            },
        })

    return locals()
Example #26
0
def gen_mesh_from_poly(filename, verbose=True):
    """
    Import mesh generated by tetgen or triangle.

    Parameters
    ----------
    filename : string
        file name

    Returns
    -------
    mesh : Mesh instance
        triangular or tetrahedral mesh
    """
    def getnodes(fnods, up):
        f = file(fnods)
        l = [int(x) for x in f.readline().split()]
        npoints, dim, nattrib, nbound = l
        if verbose: up.init(npoints)
        nodes = []
        for line in f:
            if line[0] == "#": continue
            l = [float(x) for x in line.split()]
            l = l[:(dim + 1)]
            l[0] = int(l[0])
            nodes.append(tuple(l))
            assert l[0] == len(nodes)
        assert npoints == len(nodes)
        return nodes

    def getele(fele, up):
        f = file(fele)
        l = [int(x) for x in f.readline().split()]
        nele, nnod, nattrib = l
        #we have either linear or quadratic tetrahedra:
        if nnod in [4, 10]:
            elem = 'tetra'
            linear = (nnod == 4)
        if nnod in [3, 7]:
            elem = 'tri'
            linear = (nnod == 3)

        # if nattrib!=1:
        #     raise "tetgen didn't assign an entity number to each element (option -A)"
        els = []
        regions = {}
        for line in f:
            if line[0] == "#": continue
            l = [int(x) for x in line.split()]
            if elem == 'tri':
                if linear:
                    assert (len(l) - 1 - nattrib) == 3
                    els.append((l[0], l[1], l[2], l[3]))
                    regionnum = l[5]
                else:
                    assert len(l) - 2 == 10
                    els.append((l[0], 54, l[1], l[2], l[3], l[4], l[5], l[6],
                                l[7], l[8], l[9], l[10]))
                    regionnum = l[11]
            if elem == 'tetra':
                if linear:
                    assert len(l) - 2 == 4
                    els.append((l[0], 54, l[1], l[2], l[3], l[4]))
                    regionnum = l[5]
                else:
                    assert len(l) - 2 == 10
                    els.append((l[0], 54, l[1], l[2], l[3], l[4], l[5], l[6],
                                l[7], l[8], l[9], l[10]))
                    regionnum = l[11]
            if regionnum == 0:
                print "see %s, element # %d" % (fele, l[0])
                raise "there are elements not belonging to any physical entity"
            if regions.has_key(regionnum):
                regions[regionnum].append(l[0])
            else:
                regions[regionnum] = [l[0]]
            assert l[0] == len(els)
            if verbose: up.update(l[0])
        return els, regions, linear

    def getBCfaces(ffaces, up):
        f = file(ffaces)
        l = [int(x) for x in f.readline().split()]
        nfaces, nattrib = l
        if nattrib != 1:
            raise "tetgen didn't assign an entity number to each face \
(option -A)"

        if verbose: up.init(nfaces)
        faces = {}
        for line in f:
            if line[0] == "#": continue
            l = [int(x) for x in line.split()]
            assert len(l) == 5
            regionnum = l[4]
            if regionnum == 0: continue
            if faces.has_key(regionnum):
                faces[regionnum].append((l[1], l[2], l[3]))
            else:
                faces[regionnum] = [(l[1], l[2], l[3])]
            if verbose: up.update(l[0])
        return faces

    def calculatexyz(nodes, els):
        """Calculate the missing xyz values in place"""
        def avg(i, j, n4, nodes):
            a = nodes[n4[i - 1] - 1]
            b = nodes[n4[j - 1] - 1]
            return (a[1] + b[1]) / 2, (a[2] + b[2]) / 2, (a[3] + b[3]) / 2

        def getxyz(i, n4, nodes):
            if i + 5 == 5: return avg(1, 2, n4, nodes)
            if i + 5 == 6: return avg(2, 3, n4, nodes)
            if i + 5 == 7: return avg(1, 3, n4, nodes)
            if i + 5 == 8: return avg(1, 4, n4, nodes)
            if i + 5 == 9: return avg(2, 4, n4, nodes)
            if i + 5 == 10: return avg(3, 4, n4, nodes)
            raise "wrong topology"

        for e in els:
            n4 = e[2:2 + 4]
            n6 = e[2 + 4:2 + 4 + 10]
            for i, n in enumerate(n6):
                x, y, z = getxyz(i, n4, nodes)
                nodes[n - 1] = (n, x, y, z)

    if verbose: print "Reading geometry from poly file..."
    m = Mesh()
    m.nodes = getnodes(filename + ".node")
    m.elements, m.regions, lin = getele(filename + ".ele")
    if not lin:
        #tetgen doesn't compute xyz coordinates of the aditional 6 nodes
        #(only of the 4 corner nodes) in tetrahedra.
        calculatexyz(m.nodes, m.elements)
    m.faces = getBCfaces(filename + ".face")

    return m
Example #27
0
    def linearize(self, dofs, min_level=0, max_level=1, eps=1e-4):
        """
        Linearize the solution for post-processing.

        Parameters
        ----------
        dofs : array, shape (n_nod, n_component)
            The array of DOFs reshaped so that each column corresponds
            to one component.
        min_level : int
            The minimum required level of mesh refinement.
        max_level : int
            The maximum level of mesh refinement.
        eps : float
            The relative tolerance parameter of mesh adaptivity.

        Returns
        -------
        mesh : Mesh instance
            The adapted, nonconforming, mesh.
        vdofs : array
            The DOFs defined in vertices of `mesh`.
        levels : array of ints
            The refinement level used for each element group.
        """
        assert_(dofs.ndim == 2)

        n_nod, dpn = dofs.shape

        assert_(n_nod == self.n_nod)
        assert_(dpn == self.shape[0])

        vertex_coors = self.coors[:self.n_vertex_dof, :]

        coors = []
        vdofs = []
        conns = []
        mat_ids = []
        levels = []
        offset = 0
        for ig, ap in self.aps.iteritems():
            ps = ap.interp.poly_spaces['v']
            gps = ap.interp.gel.interp.poly_spaces['v']
            group = self.domain.groups[ig]
            vertex_conn = ap.econn[:, :group.shape.n_ep]

            eval_dofs = get_eval_dofs(dofs, ap.econn, ps, ori=ap.ori)
            eval_coors = get_eval_coors(vertex_coors, vertex_conn, gps)

            (level, _coors, conn,
             _vdofs, _mat_ids) = create_output(eval_dofs, eval_coors,
                                               group.shape.n_el, ps,
                                               min_level=min_level,
                                               max_level=max_level, eps=eps)

            _mat_ids[:] = self.domain.mesh.mat_ids[ig][0]

            coors.append(_coors)
            vdofs.append(_vdofs)
            conns.append(conn + offset)
            mat_ids.append(_mat_ids)
            levels.append(level)

            offset += _coors.shape[0]

        coors = nm.concatenate(coors, axis=0)
        vdofs = nm.concatenate(vdofs, axis=0)
        mesh = Mesh.from_data('linearized_mesh', coors, None, conns, mat_ids,
                              self.domain.mesh.descs)

        return mesh, vdofs, levels
Example #28
0
def gen_mesh_from_poly(filename, verbose=True):
    """
    Import mesh generated by tetgen or triangle.

    Parameters
    ----------
    filename : string
        file name

    Returns
    -------
    mesh : Mesh instance
        triangular or tetrahedral mesh
    """

    def getnodes(fnods,up):
        f=file(fnods)
        l=[int(x) for x in f.readline().split()]
        npoints,dim,nattrib,nbound=l
        if verbose: up.init(npoints)
        nodes=[]
        for line in f:
            if line[0]=="#": continue
            l=[float(x) for x in line.split()]
            l = l[:(dim + 1)]
            l[0]=int(l[0])
            nodes.append(tuple(l))
            assert l[0]==len(nodes)
        assert npoints==len(nodes)
        return nodes

    def getele(fele,up):
        f=file(fele)
        l=[int(x) for x in f.readline().split()]
        nele,nnod,nattrib=l
        #we have either linear or quadratic tetrahedra:
        if nnod in [4,10]:
            elem = 'tetra'
            linear = (nnod == 4)
        if nnod in [3, 7]:
            elem = 'tri'
            linear = (nnod == 3)

        # if nattrib!=1:
        #     raise "tetgen didn't assign an entity number to each element (option -A)"
        els=[]
        regions={}
        for line in f:
            if line[0]=="#": continue
            l=[int(x) for x in line.split()]
            if elem == 'tri':
                if linear:
                    assert (len(l) - 1 - nattrib) == 3
                    els.append((l[0],l[1],l[2],l[3]))
                    regionnum=l[5]
                else:
                    assert len(l)-2 == 10
                    els.append((l[0],54,l[1],l[2],l[3],l[4],
                                l[5],l[6],l[7],l[8],l[9],l[10]))
                    regionnum=l[11]
            if elem == 'tetra':
                if linear:
                    assert len(l)-2 == 4
                    els.append((l[0],54,l[1],l[2],l[3],l[4]))
                    regionnum=l[5]
                else:
                    assert len(l)-2 == 10
                    els.append((l[0],54,l[1],l[2],l[3],l[4],
                                l[5],l[6],l[7],l[8],l[9],l[10]))
                    regionnum=l[11]
            if regionnum==0:
                print "see %s, element # %d"%(fele,l[0])
                raise "there are elements not belonging to any physical entity"
            if regions.has_key(regionnum):
                regions[regionnum].append(l[0])
            else:
                regions[regionnum]=[l[0]]
            assert l[0]==len(els)
            if verbose: up.update(l[0])
        return els,regions,linear

    def getBCfaces(ffaces,up):
        f=file(ffaces)
        l=[int(x) for x in f.readline().split()]
        nfaces,nattrib=l
        if nattrib!=1:
            raise "tetgen didn't assign an entity number to each face \
(option -A)"
        if verbose: up.init(nfaces)
        faces={}
        for line in f:
            if line[0]=="#": continue
            l=[int(x) for x in line.split()]
            assert len(l)==5
            regionnum=l[4]
            if regionnum==0: continue
            if faces.has_key(regionnum):
                faces[regionnum].append((l[1],l[2],l[3]))
            else:
                faces[regionnum]=[(l[1],l[2],l[3])]
            if verbose: up.update(l[0])
        return faces

    def calculatexyz(nodes, els):
        """Calculate the missing xyz values in place"""
        def avg(i,j,n4,nodes):
            a=nodes[n4[i-1]-1]
            b=nodes[n4[j-1]-1]
            return (a[1]+b[1])/2, (a[2]+b[2])/2, (a[3]+b[3])/2
        def getxyz(i,n4,nodes):
            if i+5==5: return avg(1,2,n4,nodes)
            if i+5==6: return avg(2,3,n4,nodes)
            if i+5==7: return avg(1,3,n4,nodes)
            if i+5==8: return avg(1,4,n4,nodes)
            if i+5==9: return avg(2,4,n4,nodes)
            if i+5==10: return avg(3,4,n4,nodes)
            raise "wrong topology"
        for e in els:
            n4=e[2:2+4]
            n6=e[2+4:2+4+10]
            for i,n in enumerate(n6):
                x,y,z=getxyz(i,n4,nodes)
                nodes[n-1]=(n,x,y,z)

    if verbose: print "Reading geometry from poly file..."
    m=Mesh()
    m.nodes=getnodes(filename+".node")
    m.elements,m.regions, lin=getele(filename+".ele")
    if not lin:
        #tetgen doesn't compute xyz coordinates of the aditional 6 nodes
        #(only of the 4 corner nodes) in tetrahedra.
        calculatexyz(m.nodes,m.elements)
    m.faces=getBCfaces(filename+".face")

    return m
Example #29
0
def gen_mesh_from_goem(geo, a=None, quadratic=False, verbose=True,
                       refine=False, polyfilename='./meshgen.poly',
                       out='mesh', **kwargs):
    """
    Runs mesh generator - tetgen for 3D or triangle for 2D meshes.

    Parameters
    ----------
    geo : geometry
        geometry description
    a : int, optional
        a maximum area/volume constraint
    quadratic : bool, optional
        set True for quadratic elements
    verbose : bool, optional
        detailed information
    refine : bool, optional
        refines mesh

    Returns
    -------
    mesh : Mesh instance
        triangular or tetrahedral mesh
    """

    import os.path as op
    import pexpect

    # write geometry to poly file
    geo.to_poly_file(polyfilename)

    if not refine:
        params = "-Apq"
    else:
        params = "-Arq"
    if verbose:
        params = params + " -Q"
    if a != None and not refine:
        params = params + " -a%f" % (a)
    if refine:
        params = params + " -a"
    if quadratic:
        params = params + " -o2"
    params = params + " %s" % (polyfilename)

    meshgen_call = {2: 'triangle', 3: 'tetgen'}
    cmd = "%s %s" % (meshgen_call[geo.dim], params)
    if verbose: print "Generating mesh using", cmd
    if geo.dim == 2:
        p=pexpect.run(cmd, timeout=None)
        bname, ext = op.splitext(polyfilename)
        mesh = Mesh.from_file(bname + '.1.node')
        mesh.write(bname + '.' + out)
    if geo.dim == 3:
        p=pexpect.spawn(cmd, timeout=None)
        if not refine:
            p.expect("Opening %s." % (polyfilename))
        else:
            p.expect("Opening %s.node.\r\n" % (polyfilename))
            p.expect("Opening %s.ele.\r\n" % (polyfilename))
            p.expect("Opening %s.face.\r\n" % (polyfilename))
            p.expect("Opening %s.vol." % (polyfilename))
        assert p.before == ""
        p.expect(pexpect.EOF)
        if p.before != "\r\n":
            print p.before
            raise "Error when running mesh generator (see above for output): %s" % cmd
Example #30
0
def gen_tiled_mesh(mesh, grid=None, scale=1.0, eps=1e-6, ret_ndmap=False):
    """
    Generate a new mesh by repeating a given periodic element
    along each axis.

    Parameters
    ----------
    mesh : Mesh instance
        The input periodic FE mesh.
    grid : array
        Number of repetition along each axis.
    scale : float, optional
        Scaling factor.
    eps : float, optional
        Tolerance for boundary detection.
    ret_ndmap : bool, optional
        If True, return global node map.

    Returns
    -------
    mesh_out : Mesh instance
        FE mesh.
    ndmap : array
        Maps: actual node id --> node id in the reference cell.
    """
    bbox = mesh.get_bounding_box()

    if grid is None:
        iscale = max(int(1.0 / scale), 1)
        grid = [iscale] * mesh.dim

    conns = mesh.conns[0]
    for ii in mesh.conns[1:]:
        conns = nm.vstack((conns, ii))
    mat_ids = mesh.mat_ids[0]
    for ii in mesh.mat_ids[1:]:
        mat_ids = nm.hstack((mat_ids, ii))

    coors = mesh.coors
    ngrps = mesh.ngroups
    nrep = nm.prod(grid)
    ndmap = None

    output('repeating %s ...' % grid)
    nblk = 1
    for ii, gr in enumerate(grid):
        if ret_ndmap:
            (conns, coors,
             ngrps, ndmap0) = tiled_mesh1d(conns, coors, ngrps,
                                           ii, gr, bbox.transpose()[ii],
                                           eps=eps, ndmap=ndmap)
            ndmap = ndmap0

        else:
            conns, coors, ngrps = tiled_mesh1d(conns, coors, ngrps,
                                               ii, gr, bbox.transpose()[ii],
                                               eps=eps)
        nblk *= gr

    output('...done')

    mat_ids = nm.tile(mat_ids, (nrep,))
    mesh_out = Mesh.from_data('tiled mesh', coors * scale, ngrps,
                              [conns], [mat_ids], [mesh.descs[0]])

    if ret_ndmap:
        return mesh_out, ndmap
    else:
        return mesh_out
Example #31
0
    def save_state(self, filename, state=None, out=None,
                   fill_value=None, post_process_hook=None,
                   linearization=None, file_per_var=False, **kwargs):
        """
        Parameters
        ----------
        file_per_var : bool or None
            If True, data of each variable are stored in a separate
            file. If None, it is set to the application option value.
        linearization : Struct or None
            The linearization configuration for higher order
            approximations. If its kind is 'adaptive', `file_per_var` is
            assumed True.
        """
        linearization = get_default(linearization, self.linearization)
        if linearization.kind != 'adaptive':
            file_per_var = get_default(file_per_var, self.file_per_var)

        else:
            file_per_var = True

        extend = not file_per_var
        if (out is None) and (state is not None):
            out = state.create_output_dict(fill_value=fill_value,
                                           extend=extend,
                                           linearization=linearization)

            if post_process_hook is not None:
                out = post_process_hook(out, self, state, extend=extend)

        if linearization.kind == 'adaptive':
            for key, val in out.iteritems():
                mesh = val.get('mesh', self.domain.mesh)
                aux = io.edit_filename(filename, suffix='_' + val.var_name)
                mesh.write(aux, io='auto', out={key : val},
                           float_format=self.float_format, **kwargs)
                if hasattr(val, 'levels'):
                    output('max. refinement per group:', val.levels)

        elif file_per_var:
            meshes = {}

            if self.equations is None:
                varnames = {}
                for key, val in out.iteritems():
                    varnames[val.var_name] = 1
                varnames = varnames.keys()
                outvars = self.create_variables(varnames)
                itervars = outvars.__iter__
            else:
                itervars = self.equations.variables.iter_state

            for var in itervars():
                rname = var.field.region.name
                if meshes.has_key(rname):
                    mesh = meshes[rname]
                else:
                    mesh = Mesh.from_region(var.field.region, self.domain.mesh,
                                            localize=True,
                                            is_surface=var.is_surface)
                    meshes[rname] = mesh

                vout = {}
                for key, val in out.iteritems():
                    try:
                        if val.var_name == var.name:
                            vout[key] = val

                    except AttributeError:
                        msg = 'missing var_name attribute in output!'
                        raise ValueError(msg)

                aux = io.edit_filename(filename, suffix='_' + var.name)
                mesh.write(aux, io='auto', out=vout,
                           float_format=self.float_format, **kwargs)
        else:
            mesh = out.pop('__mesh__', self.domain.mesh)
            mesh.write(filename, io='auto', out=out,
                       float_format=self.float_format, **kwargs)
Example #32
0
def gen_mesh_from_voxels(voxels, dims, etype='q'):
    """
    Generate FE mesh from voxels (volumetric data).

    Parameters
    ----------
    voxels : array
        Voxel matrix, 1=material.
    dims : array
        Size of one voxel.
    etype : integer, optional
        'q' - quadrilateral or hexahedral elements
        't' - triangular or tetrahedral elements
    Returns
    -------
    mesh : Mesh instance
        Finite element mesh.
    """

    dims = nm.array(dims).squeeze()
    dim = len(dims)
    nddims = nm.array(voxels.shape) + 2

    nodemtx = nm.zeros(nddims, dtype=nm.int32)

    if dim == 2:
        #iy, ix = nm.where(voxels.transpose())
        iy, ix = nm.where(voxels)
        nel = ix.shape[0]

        if etype == 'q':
            nodemtx[ix,iy] += 1
            nodemtx[ix + 1,iy] += 1
            nodemtx[ix + 1,iy + 1] += 1
            nodemtx[ix,iy + 1] += 1

        elif etype == 't':
            nodemtx[ix,iy] += 2
            nodemtx[ix + 1,iy] += 1
            nodemtx[ix + 1,iy + 1] += 2
            nodemtx[ix,iy + 1] += 1
            nel *= 2

    elif dim == 3:
        #iy, ix, iz = nm.where(voxels.transpose(1, 0, 2))
        iy, ix, iz = nm.where(voxels)
        nel = ix.shape[0]

        if etype == 'q':
            nodemtx[ix,iy,iz] += 1
            nodemtx[ix + 1,iy,iz] += 1
            nodemtx[ix + 1,iy + 1,iz] += 1
            nodemtx[ix,iy + 1,iz] += 1
            nodemtx[ix,iy,iz + 1] += 1
            nodemtx[ix + 1,iy,iz + 1] += 1
            nodemtx[ix + 1,iy + 1,iz + 1] += 1
            nodemtx[ix,iy + 1,iz + 1] += 1

        elif etype == 't':
            nodemtx[ix,iy,iz] += 6
            nodemtx[ix + 1,iy,iz] += 2
            nodemtx[ix + 1,iy + 1,iz] += 2
            nodemtx[ix,iy + 1,iz] += 2
            nodemtx[ix,iy,iz + 1] += 2
            nodemtx[ix + 1,iy,iz + 1] += 2
            nodemtx[ix + 1,iy + 1,iz + 1] += 6
            nodemtx[ix,iy + 1,iz + 1] += 2
            nel *= 6

    else:
        msg = 'incorrect voxel dimension! (%d)' % dim
        raise ValueError(msg)

    ndidx = nm.where(nodemtx)
    coors = nm.array(ndidx).transpose() * dims
    nnod = coors.shape[0]

    nodeid = -nm.ones(nddims, dtype=nm.int32)
    nodeid[ndidx] = nm.arange(nnod)

    # generate elements
    if dim == 2:
        elems = nm.array([nodeid[ix,iy],
                          nodeid[ix + 1,iy],
                          nodeid[ix + 1,iy + 1],
                          nodeid[ix,iy + 1]]).transpose()

    elif dim == 3:
        elems = nm.array([nodeid[ix,iy,iz],
                          nodeid[ix + 1,iy,iz],
                          nodeid[ix + 1,iy + 1,iz],
                          nodeid[ix,iy + 1,iz],
                          nodeid[ix,iy,iz + 1],
                          nodeid[ix + 1,iy,iz + 1],
                          nodeid[ix + 1,iy + 1,iz + 1],
                          nodeid[ix,iy + 1,iz + 1]]).transpose()

    if etype == 't':
        elems = elems_q2t(elems)

    eid = etype + str(dim)
    eltab = {'q2': 4, 'q3': 8, 't2': 3, 't3': 4}

    mesh = Mesh.from_data('voxel_data',
                          coors, nm.ones((nnod,), dtype=nm.int32),
                          [nm.ascontiguousarray(elems)],
                          [nm.ones((nel,), dtype=nm.int32)],
                          ['%d_%d' % (dim, eltab[eid])])

    return mesh
Example #33
0
def define(eps0=1e-3, filename_mesh='meshes/3d/piezo_mesh_micro.vtk'):

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

    regions.update({
        'Ymc': 'all',
        # matrix
        'Ym': 'cells of group 1',
        'Ym_left': ('r.Ym *v r.Left', 'vertex'),
        'Ym_right': ('r.Ym *v r.Right', 'vertex'),
        'Ym_bottom': ('r.Ym *v r.Bottom', 'vertex'),
        'Ym_top': ('r.Ym *v r.Top', 'vertex'),
        'Ym_far': ('r.Ym *v r.Far', 'vertex'),
        'Ym_near': ('r.Ym *v r.Near', 'vertex'),
        'Gamma_ms': ('r.Ym *v r.Yc', 'facet', 'Ym'),
        # conductors
        'Yc': ('r.Yc1 +c r.Yc2', 'cell'),
        'Yc1': 'cells of group 2',
        'Yc2': 'cells of group 3',
        'Gamma_s1': ('r.Ym *v r.Yc1', 'facet', 'Ym'),
        'Gamma_s2': ('r.Ym *v r.Yc2', 'facet', 'Ym'),
    })

    options = {
        'coefs_filename': 'coefs_piezo',
        'volume': {
            'value': nm.prod(bbox[1] - bbox[0])
        },
        'coefs': 'coefs',
        'requirements': 'requirements',
        'output_dir': 'output',
        'file_per_var': True,
        'absolute_mesh_path': True,
        'multiprocessing': False,
        'recovery_hook': recovery_micro,
    }

    fields = {
        'displacement': ('real', 'vector', 'Ymc', 1),
        'potential': ('real', 'scalar', 'Ym', 1),
        'sfield': ('real', 'scalar', 'Ymc', 1),
    }

    variables = {
        # displacement
        'u': ('unknown field', 'displacement'),
        'v': ('test field', 'displacement', 'u'),
        'Pi_u': ('parameter field', 'displacement', 'u'),
        'U1': ('parameter field', 'displacement', '(set-to-None)'),
        'U2': ('parameter field', 'displacement', '(set-to-None)'),
        # potential
        'r': ('unknown field', 'potential'),
        's': ('test field', 'potential', 'r'),
        'Pi_r': ('parameter field', 'potential', 'r'),
        'R1': ('parameter field', 'potential', '(set-to-None)'),
        'R2': ('parameter field', 'potential', '(set-to-None)'),
        # auxiliary
        'svar': ('parameter field', 'sfield', '(set-to-None)'),
    }

    epbcs = {
        'p_ux': (['Left', 'Right'], {
            'u.all': 'u.all'
        }, 'match_x_plane'),
        'p_uy': (['Near', 'Far'], {
            'u.all': 'u.all'
        }, 'match_y_plane'),
        'p_uz': (['Bottom', 'Top'], {
            'u.all': 'u.all'
        }, 'match_z_plane'),
        'p_rx': (['Ym_left', 'Ym_right'], {
            'r.0': 'r.0'
        }, 'match_x_plane'),
        'p_ry': (['Ym_near', 'Ym_far'], {
            'r.0': 'r.0'
        }, 'match_y_plane'),
        'p_rz': (['Ym_bottom', 'Ym_top'], {
            'r.0': 'r.0'
        }, 'match_z_plane'),
    }

    periodic = {
        'per_u': ['per_u_x', 'per_u_y', 'per_u_z'],
        'per_r': ['per_r_x', 'per_r_y', 'per_r_z'],
    }

    # rescale piezoelectric material parameters
    mat_g_sc, mat_d_sc = (eps0, eps0**2)

    materials = {
        'elastic': ({
            'D': {
                'Ym':
                nm.array([[1.504, 0.656, 0.659, 0, 0, 0],
                          [0.656, 1.504, 0.659, 0, 0, 0],
                          [0.659, 0.659, 1.455, 0, 0, 0],
                          [0, 0, 0, 0.424, 0, 0], [0, 0, 0, 0, 0.439, 0],
                          [0, 0, 0, 0, 0, 0.439]]) * 1e11,
                'Yc':
                stiffness_from_youngpoisson(3, 200e9, 0.25)
            }
        }, ),
        'piezo': ({
            'g':
            nm.array([[0, 0, 0, 0, 11.404, 0], [0, 0, 0, 0, 0, 11.404],
                      [-4.322, -4.322, 17.360, 0, 0, 0]]) / mat_g_sc,
            'd':
            nm.array([[1.284, 0, 0], [0, 1.284, 0], [0, 0, 1.505]]) * 1e-8 /
            mat_d_sc
        }, ),
    }

    functions = {
        'match_x_plane': (per.match_x_plane, ),
        'match_y_plane': (per.match_y_plane, ),
        'match_z_plane': (per.match_z_plane, ),
    }

    ebcs = {
        'fixed_u': ('Corners', {
            'u.all': 0.0
        }),
        'fixed_r': ('Gamma_ms', {
            'r.all': 0.0
        }),
        'fixed_r1_s1': ('Gamma_s1', {
            'r.0': 1.0
        }),
        'fixed_r0_s1': ('Gamma_s1', {
            'r.0': 0.0
        }),
        'fixed_r1_s2': ('Gamma_s2', {
            'r.0': 1.0
        }),
        'fixed_r0_s2': ('Gamma_s2', {
            'r.0': 0.0
        }),
    }

    integrals = {
        'i2': 2,
    }

    solvers = {
        'ls_d': ('ls.scipy_direct', {}),
        'ls_i': ('ls.scipy_iterative', {}),
        'ns_ea6': ('nls.newton', {
            'eps_a': 1e6,
            'eps_r': 1e-3,
        }),
        'ns_ea0': ('nls.newton', {
            'eps_a': 1e0,
            'eps_r': 1e-3,
        }),
    }

    coefs = {
        'A1': {
            'status':
            'auxiliary',
            'requires': ['pis_u', 'corrs_rs'],
            'expression':
            'dw_lin_elastic.i2.Ymc(elastic.D, U1, U2)',
            'set_variables': [('U1', ('corrs_rs', 'pis_u'), 'u'),
                              ('U2', ('corrs_rs', 'pis_u'), 'u')],
            'class':
            cb.CoefSymSym,
        },
        'A2': {
            'status': 'auxiliary',
            'requires': ['corrs_rs'],
            'expression': 'dw_diffusion.i2.Ym(piezo.d, R1, R2)',
            'set_variables': [('R1', 'corrs_rs', 'r'),
                              ('R2', 'corrs_rs', 'r')],
            'class': cb.CoefSymSym,
        },
        'A': {
            'requires': ['c.A1', 'c.A2'],
            'expression': 'c.A1 + c.A2',
            'class': cb.CoefEval,
        },
        'vol': {
            'regions': ['Ym', 'Yc1', 'Yc2'],
            'expression': 'ev_volume.i2.%s(svar)',
            'class': cb.VolumeFractions,
        },
        'eps0': {
            'requires': [],
            'expression': '%e' % eps0,
            'class': cb.CoefEval,
        },
        'filenames': {},
    }

    requirements = {
        'pis_u': {
            'variables': ['u'],
            'class': cb.ShapeDimDim,
        },
        'pis_r': {
            'variables': ['r'],
            'class': cb.ShapeDim,
        },
        'corrs_rs': {
            'requires': ['pis_u'],
            'ebcs': ['fixed_u', 'fixed_r'],
            'epbcs': ['p_ux', 'p_uy', 'p_uz', 'p_rx', 'p_ry', 'p_rz'],
            'equations': {
                'eq1':
                """dw_lin_elastic.i2.Ymc(elastic.D, v, u)
                     - dw_piezo_coupling.i2.Ym(piezo.g, v, r)
                   = - dw_lin_elastic.i2.Ymc(elastic.D, v, Pi_u)""",
                'eq2':
                """
                     - dw_piezo_coupling.i2.Ym(piezo.g, u, s)
                     - dw_diffusion.i2.Ym(piezo.d, s, r)
                     = dw_piezo_coupling.i2.Ym(piezo.g, Pi_u, s)""",
            },
            'set_variables': [('Pi_u', 'pis_u', 'u')],
            'class': cb.CorrDimDim,
            'save_name': 'corrs_rs',
            'solvers': {
                'ls': 'ls_i',
                'nls': 'ns_ea6'
            },
        },
    }

    # define requirements and coefficients related to conductors
    bc_conductors = [
        ['fixed_r1_s1', 'fixed_r0_s2'],  # phi = 1 on S1, phi = 0 on S2
        ['fixed_r1_s2', 'fixed_r0_s1'],  # phi = 0 on S1, phi = 1 on S2
    ]

    for k in range(2):
        sk = '%d' % k

        requirements.update({
            'corrs_k' + sk: {
                'requires': ['pis_r'],
                'ebcs': ['fixed_u'] + bc_conductors[k],
                'epbcs': ['p_ux', 'p_uy', 'p_uz', 'p_rx', 'p_ry', 'p_rz'],
                'equations': {
                    'eq1':
                    """dw_lin_elastic.i2.Ymc(elastic.D, v, u)
                         - dw_piezo_coupling.i2.Ym(piezo.g, v, r)
                         = 0""",
                    'eq2':
                    """
                         - dw_piezo_coupling.i2.Ym(piezo.g, u, s)
                         - dw_diffusion.i2.Ym(piezo.d, s, r)
                         = 0"""
                },
                'class': cb.CorrOne,
                'save_name': 'corrs_k' + sk,
                'solvers': {
                    'ls': 'ls_d',
                    'nls': 'ns_ea0'
                },
            },
        })

        coefs.update({
            'V1_' + sk: {
                'status':
                'auxiliary',
                'requires': ['pis_u', 'corrs_k' + sk],
                'expression':
                'dw_lin_elastic.i2.Ymc(elastic.D, U1, U2)',
                'set_variables': [('U1', 'corrs_k' + sk, 'u'),
                                  ('U2', 'pis_u', 'u')],
                'class':
                cb.CoefSym,
            },
            'V2_' + sk: {
                'status':
                'auxiliary',
                'requires': ['pis_u', 'corrs_k' + sk],
                'expression':
                'dw_piezo_coupling.i2.Ym(piezo.g, U1, R1)',
                'set_variables': [('R1', 'corrs_k' + sk, 'r'),
                                  ('U1', 'pis_u', 'u')],
                'class':
                cb.CoefSym,
            },
            'V' + sk: {
                'requires': ['c.V1_' + sk, 'c.V2_' + sk],
                'expression': 'c.V1_%s - c.V2_%s' % (sk, sk),
                'class': cb.CoefEval,
            },
        })

    return locals()
Example #34
0
def define(is_opt=False):
    filename_mesh = data_dir + "/meshes/3d/matrix_fiber_rand.vtk"

    mesh = Mesh.from_file(filename_mesh)
    bbox = mesh.get_bounding_box()

    regions = {"Y": "all", "Ym": ("cells of group 7", "cell"), "Yf": ("r.Y -c r.Ym", "cell")}

    regions.update(define_box_regions(3, bbox[0], bbox[1]))

    functions = {
        "get_mat": (lambda ts, coors, mode=None, problem=None, **kwargs: get_mat(coors, mode, problem),),
        "match_x_plane": (per.match_x_plane,),
        "match_y_plane": (per.match_y_plane,),
        "match_z_plane": (per.match_z_plane,),
    }

    materials = {"mat": "get_mat"}

    fields = {"corrector": ("real", 3, "Y", 1)}

    variables = {
        "u": ("unknown field", "corrector"),
        "v": ("test field", "corrector", "u"),
        "Pi": ("parameter field", "corrector", "u"),
        "Pi1": ("parameter field", "corrector", "(set-to-None)"),
        "Pi2": ("parameter field", "corrector", "(set-to-None)"),
    }

    ebcs = {"fixed_u": ("Corners", {"u.all": 0.0})}

    epbcs = {
        "periodic_x": (["Left", "Right"], {"u.all": "u.all"}, "match_x_plane"),
        "periodic_y": (["Near", "Far"], {"u.all": "u.all"}, "match_y_plane"),
        "periodic_z": (["Top", "Bottom"], {"u.all": "u.all"}, "match_z_plane"),
    }

    all_periodic = ["periodic_%s" % ii for ii in ["x", "y", "z"][:3]]

    options = {
        "coefs": "coefs",
        "requirements": "requirements",
        "volume": {"variables": ["u"], "expression": "d_volume.5.Y( u )"},
        "output_dir": "output",
        "coefs_filename": "coefs_le",
    }

    equation_corrs = {
        "balance_of_forces": """dw_lin_elastic.5.Y(mat.D, v, u)
                = - dw_lin_elastic.5.Y(mat.D, v, Pi)"""
    }

    coefs = {
        "D": {
            "requires": ["pis", "corrs_rs"],
            "expression": "dw_lin_elastic.5.Y(mat.D, Pi1, Pi2 )",
            "set_variables": [("Pi1", ("pis", "corrs_rs"), "u"), ("Pi2", ("pis", "corrs_rs"), "u")],
            "class": cb.CoefSymSym,
        },
        "vol": {"regions": ["Ym", "Yf"], "expression": "d_volume.5.%s(u)", "class": cb.VolumeFractions},
        "filenames": {},
    }

    requirements = {
        "pis": {"variables": ["u"], "class": cb.ShapeDimDim},
        "corrs_rs": {
            "requires": ["pis"],
            "ebcs": ["fixed_u"],
            "epbcs": all_periodic,
            "equations": equation_corrs,
            "set_variables": [("Pi", "pis", "u")],
            "class": cb.CorrDimDim,
            "save_name": "corrs_le",
            "dump_variables": ["u"],
        },
    }

    solvers = {
        "ls": ("ls.scipy_direct", {}),
        "newton": ("nls.newton", {"i_max": 1, "eps_a": 1e-4, "problem": "linear"}),
    }

    if is_opt:
        options.update({"parametric_hook": "optimization_hook", "float_format": "%.16e"})

    return locals()
Example #35
0
def gen_mesh_from_goem(geo,
                       a=None,
                       quadratic=False,
                       verbose=True,
                       refine=False,
                       polyfilename='./meshgen.poly',
                       out='mesh',
                       **kwargs):
    """
    Runs mesh generator - tetgen for 3D or triangle for 2D meshes.

    Parameters
    ----------
    geo : geometry
        geometry description
    a : int, optional
        a maximum area/volume constraint
    quadratic : bool, optional
        set True for quadratic elements
    verbose : bool, optional
        detailed information
    refine : bool, optional
        refines mesh

    Returns
    -------
    mesh : Mesh instance
        triangular or tetrahedral mesh
    """

    import os.path as op
    import pexpect

    # write geometry to poly file
    geo.to_poly_file(polyfilename)

    if not refine:
        params = "-Apq"
    else:
        params = "-Arq"
    if verbose:
        params = params + " -Q"
    if a != None and not refine:
        params = params + " -a%f" % (a)
    if refine:
        params = params + " -a"
    if quadratic:
        params = params + " -o2"
    params = params + " %s" % (polyfilename)

    meshgen_call = {2: 'triangle', 3: 'tetgen'}
    cmd = "%s %s" % (meshgen_call[geo.dim], params)
    if verbose: print "Generating mesh using", cmd
    if geo.dim == 2:
        p = pexpect.run(cmd, timeout=None)
        bname, ext = op.splitext(polyfilename)
        mesh = Mesh.from_file(bname + '.1.node')
        mesh.write(bname + '.' + out)
    if geo.dim == 3:
        p = pexpect.spawn(cmd, timeout=None)
        if not refine:
            p.expect("Opening %s." % (polyfilename))
        else:
            p.expect("Opening %s.node.\r\n" % (polyfilename))
            p.expect("Opening %s.ele.\r\n" % (polyfilename))
            p.expect("Opening %s.face.\r\n" % (polyfilename))
            p.expect("Opening %s.vol." % (polyfilename))
        assert p.before == ""
        p.expect(pexpect.EOF)
        if p.before != "\r\n":
            print p.before
            raise "Error when running mesh generator (see above for output): %s" % cmd
Example #36
0
def gen_cylinder_mesh(dims, shape, centre, axis='x', force_hollow=False,
                      is_open=False, open_angle=0.0, non_uniform=False,
                      name='cylinder', verbose=True):
    """
    Generate a cylindrical mesh along an axis. Its cross-section can be
    ellipsoidal.

    Parameters
    ----------
    dims : array of 5 floats
        Dimensions of the cylinder: inner surface semi-axes a1, b1, outer
        surface semi-axes a2, b2, length.
    shape : array of 3 ints
        Shape (counts of nodes in radial, circumferential and longitudinal
        directions) of the cylinder mesh.
    centre : array of 3 floats
        Centre of the cylinder.
    axis: one of 'x', 'y', 'z'
        The axis of the cylinder.
    force_hollow : boolean
        Force hollow mesh even if inner radii a1 = b1 = 0.
    is_open : boolean
        Generate an open cylinder segment.
    open_angle : float
        Opening angle in radians.
    non_uniform : boolean
        If True, space the mesh nodes in radial direction so that the element
        volumes are (approximately) the same, making thus the elements towards
        the outer surface thinner.
    name : string
        Mesh name.
    verbose : bool
        If True, show progress of the mesh generation.

    Returns
    -------
    mesh : Mesh instance
    """
    dims = nm.asarray(dims, dtype=nm.float64)
    shape = nm.asarray(shape, dtype=nm.int32)
    centre = nm.asarray(centre, dtype=nm.float64)

    a1, b1, a2, b2, length = dims
    nr, nfi, nl = shape
    origin = centre - nm.array([0.5 * length, 0.0, 0.0])

    dfi = 2.0 * (nm.pi - open_angle) / nfi
    if is_open:
        nnfi = nfi + 1
    else:
        nnfi = nfi

    is_hollow = force_hollow or not (max(abs(a1), abs(b1)) < 1e-15)

    if is_hollow:
        mr = 0
    else:
        mr = (nnfi - 1) * nl

    grid = nm.zeros((nr, nnfi, nl), dtype=nm.int32)

    n_nod = nr * nnfi * nl - mr
    coors = nm.zeros((n_nod, 3), dtype=nm.float64)

    angles = nm.linspace(open_angle, open_angle+(nfi)*dfi, nfi+1)
    xs = nm.linspace(0.0, length, nl)
    if non_uniform:
        ras = nm.zeros((nr,), dtype=nm.float64)
        rbs = nm.zeros_like(ras)
        advol = (a2**2 - a1**2) / (nr - 1)
        bdvol = (b2**2 - b1**2) / (nr - 1)
        ras[0], rbs[0] = a1, b1
        for ii in range(1, nr):
            ras[ii] = nm.sqrt(advol + ras[ii-1]**2)
            rbs[ii] = nm.sqrt(bdvol + rbs[ii-1]**2)
    else:
        ras = nm.linspace(a1, a2, nr)
        rbs = nm.linspace(b1, b2, nr)

    # This is 3D only...
    output('generating %d vertices...' % n_nod, verbose=verbose)
    ii = 0
    for ix in range(nr):
        a, b = ras[ix], rbs[ix]
        for iy, fi in enumerate(angles[:nnfi]):
            for iz, x in enumerate(xs):
                grid[ix,iy,iz] = ii
                coors[ii] = origin + [x, a * nm.cos(fi), b * nm.sin(fi)]
                ii += 1

                if not is_hollow and (ix == 0):
                    if iy > 0:
                        grid[ix,iy,iz] = grid[ix,0,iz]
                        ii -= 1
    assert_(ii == n_nod)
    output('...done', verbose=verbose)

    n_el = (nr - 1) * nfi * (nl - 1)
    conn = nm.zeros((n_el, 8), dtype=nm.int32)

    output('generating %d cells...' % n_el, verbose=verbose)
    ii = 0
    for (ix, iy, iz) in cycle([nr-1, nnfi, nl-1]):
        if iy < (nnfi - 1):
            conn[ii,:] = [grid[ix  ,iy  ,iz  ], grid[ix+1,iy  ,iz  ],
                          grid[ix+1,iy+1,iz  ], grid[ix  ,iy+1,iz  ],
                          grid[ix  ,iy  ,iz+1], grid[ix+1,iy  ,iz+1],
                          grid[ix+1,iy+1,iz+1], grid[ix  ,iy+1,iz+1]]
            ii += 1
        elif not is_open:
            conn[ii,:] = [grid[ix  ,iy  ,iz  ], grid[ix+1,iy  ,iz  ],
                          grid[ix+1,0,iz  ], grid[ix  ,0,iz  ],
                          grid[ix  ,iy  ,iz+1], grid[ix+1,iy  ,iz+1],
                          grid[ix+1,0,iz+1], grid[ix  ,0,iz+1]]
            ii += 1

    mat_id = nm.zeros((n_el,), dtype = nm.int32)
    desc = '3_8'

    assert_(n_nod == (conn.max() + 1))
    output('...done', verbose=verbose)

    if axis == 'z':
        coors = coors[:,[1,2,0]]
    elif axis == 'y':
        coors = coors[:,[2,0,1]]

    mesh = Mesh.from_data(name, coors, None, [conn], [mat_id], [desc])
    return mesh
Example #37
0
def define(filename_mesh=None, cg1=None, cg2=None):
    if filename_mesh is None:
        filename_mesh = osp.join(data_dir, 'macro_perf.vtk')
        cg1, cg2 = 0.0015, 0.0015  # y and z coordinates of center of gravity

    mesh = Mesh.from_file(filename_mesh)
    poroela_mezo_file = osp.join(data_dir, 'perf_BD2B_mes.py')
    material_cache['meso_filename'] = poroela_mezo_file

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

    regions.update({
        'Omega': 'all',
        'Wall': ('r.Top +v r.Bottom +v r.Far +v r.Near', 'facet'),
        # 'In': ('r.Left -v r.Wall', 'facet'),
        # 'Out': ('r.Right -v r.Wall', 'facet'),
        'In': ('copy r.Left', 'facet'),
        'Out': ('copy r.Right ', 'facet'),
        'Out_u': ('r.Out -v (r.Top +v r.Bottom)', 'facet'),
    })
    val_w1 = 5e3
    val_w2 = 5e3
    ebcs, bc_funs, mats, lcbcs = define_bc(cg1,
                                           cg2,
                                           is_steady=False,
                                           val_in=val_w1,
                                           val_out=val_w2)

    fields = {
        'displacement': ('real', 'vector', 'Omega', 1),
        'pressure': ('real', 'scalar', 'Omega', 1),
        'velocity1': ('real', 'vector', 'Omega', 1),
        'velocity2': ('real', 'vector', 'Omega', 1),
        'sfield': ('real', "scalar", 'Omega', 1),
    }

    variables = {
        #Displacement
        'u': ('unknown field', 'displacement'),
        'v': ('test field', 'displacement', 'u'),
        #Pressure
        'p': ('unknown field', 'pressure'),
        'q': ('test field', 'pressure', 'p'),
        'ls': ('unknown field', 'pressure'),
        'lv': ('test field', 'pressure', 'ls'),
        #Velocity
        'w1': ('unknown field', 'velocity1'),
        'z1': ('test field', 'velocity1', 'w1'),
        'w2': ('unknown field', 'velocity2'),
        'z2': ('test field', 'velocity2', 'w2'),
        'U': ('parameter field', 'displacement', 'u'),
        'P': ('parameter field', 'pressure', 'p'),
        'W1': ('parameter field', 'velocity1', 'w1'),
        'W2': ('parameter field', 'velocity2', 'w2'),
        'svar': ('parameter field', 'sfield', '(set-to-none)'),
    }
    state_vars = ['p', 'u', 'w1', 'w2']

    functions = {
        'get_homog': (lambda ts, coors, problem, mode=None, **kwargs: \
                          get_homog(coors,problem, mode, **kwargs),),
        'get_u': (lambda ts, coor, mode=None, problem=None, **kwargs:
                  get_u(tstep, coor),),


    }
    functions.update(bc_funs)

    materials = {
        'hom': 'get_homog',
    }
    materials.update(mats)

    #Definition of integrals
    integrals = {
        'i': 5,
        "is": ("s", 5),
    }
    #Definition of solvers
    solvers = {
        'ls': ('ls.mumps', {}),
        'newton': ('nls.newton', {
            'i_max': 1,
            'eps_a': 1e-10,
            'eps_r': 1e-3,
            'problem': 'nonlinear',
        })
    }

    options = {
        'output_dir': data_dir + '/results/macro',
        'ls': 'ls',
        'nls': 'newton',
        'micro_filename': poroela_mezo_file,
        'absolute_mesh_path': True,
        'output_prefix': 'Macro:',
        'matrix_hook': 'mtx_hook',
    }
    #Definition of time solver and equations for steady state and time evolution cases
    tstep = TimeStepper(0.0, 1.0, n_step=20)
    equations, phook = define_time_equations(tstep)

    options.update({'parametric_hook': phook})

    return locals()
Example #38
0
    def save_state(
        self,
        filename,
        state=None,
        out=None,
        fill_value=None,
        post_process_hook=None,
        linearization=None,
        file_per_var=False,
        **kwargs
    ):
        """
        Parameters
        ----------
        file_per_var : bool or None
            If True, data of each variable are stored in a separate
            file. If None, it is set to the application option value.
        linearization : Struct or None
            The linearization configuration for higher order
            approximations. If its kind is 'adaptive', `file_per_var` is
            assumed True.
        """
        linearization = get_default(linearization, self.linearization)
        if linearization.kind != "adaptive":
            file_per_var = get_default(file_per_var, self.file_per_var)

        else:
            file_per_var = True

        extend = not file_per_var
        if (out is None) and (state is not None):
            out = state.create_output_dict(fill_value=fill_value, extend=extend, linearization=linearization)

            if post_process_hook is not None:
                out = post_process_hook(out, self, state, extend=extend)

        if linearization.kind == "adaptive":
            for key, val in out.iteritems():
                mesh = val.get("mesh", self.domain.mesh)
                aux = io.edit_filename(filename, suffix="_" + val.var_name)
                mesh.write(aux, io="auto", out={key: val}, float_format=self.float_format, **kwargs)
                if hasattr(val, "levels"):
                    output("max. refinement per group:", val.levels)

        elif file_per_var:
            meshes = {}

            if self.equations is None:
                varnames = {}
                for key, val in out.iteritems():
                    varnames[val.var_name] = 1
                varnames = varnames.keys()
                outvars = self.create_variables(varnames)
                itervars = outvars.__iter__
            else:
                itervars = self.equations.variables.iter_state

            for var in itervars():
                rname = var.field.region.name
                if meshes.has_key(rname):
                    mesh = meshes[rname]
                else:
                    mesh = Mesh.from_region(
                        var.field.region, self.domain.mesh, localize=True, is_surface=var.is_surface
                    )
                    meshes[rname] = mesh

                vout = {}
                for key, val in out.iteritems():
                    try:
                        if val.var_name == var.name:
                            vout[key] = val

                    except AttributeError:
                        msg = "missing var_name attribute in output!"
                        raise ValueError(msg)

                aux = io.edit_filename(filename, suffix="_" + var.name)
                mesh.write(aux, io="auto", out=vout, float_format=self.float_format, **kwargs)
        else:
            self.domain.mesh.write(filename, io="auto", out=out, float_format=self.float_format, **kwargs)
Example #39
0
def create_expression_output(expression, name, primary_field_name,
                             fields, materials, variables,
                             functions=None, mode='eval', term_mode=None,
                             extra_args=None, verbose=True, kwargs=None,
                             min_level=0, max_level=1, eps=1e-4):
    """
    Create output mesh and data for the expression using the adaptive
    linearizer.

    Parameters
    ----------
    expression : str
        The expression to evaluate.
    name : str
        The name of the data.
    primary_field_name : str
        The name of field that defines the element groups and polynomial
        spaces.
    fields : dict
        The dictionary of fields used in `variables`.
    materials : Materials instance
        The materials used in the expression.
    variables : Variables instance
        The variables used in the expression.
    functions : Functions instance, optional
        The user functions for materials etc.
    mode : one of 'eval', 'el_avg', 'qp'
        The evaluation mode - 'qp' requests the values in quadrature points,
        'el_avg' element averages and 'eval' means integration over
        each term region.
    term_mode : str
        The term call mode - some terms support different call modes
        and depending on the call mode different values are
        returned.
    extra_args : dict, optional
        Extra arguments to be passed to terms in the expression.
    verbose : bool
        If False, reduce verbosity.
    kwargs : dict, optional
        The variables (dictionary of (variable name) : (Variable
        instance)) to be used in the expression.
    min_level : int
        The minimum required level of mesh refinement.
    max_level : int
        The maximum level of mesh refinement.
    eps : float
        The relative tolerance parameter of mesh adaptivity.

    Returns
    -------
    out : dict
        The output dictionary.
    """
    field = fields[primary_field_name]
    vertex_coors = field.coors[:field.n_vertex_dof, :]

    ps = field.poly_space
    gps = field.gel.poly_space
    vertex_conn = field.econn[:, :field.gel.n_vertex]

    eval_dofs = get_eval_expression(expression,
                                    fields, materials, variables,
                                    functions=functions,
                                    mode=mode, extra_args=extra_args,
                                    verbose=verbose, kwargs=kwargs)
    eval_coors = get_eval_coors(vertex_coors, vertex_conn, gps)

    (level, coors, conn,
     vdofs, mat_ids) = create_output(eval_dofs, eval_coors,
                                     vertex_conn.shape[0], ps,
                                     min_level=min_level,
                                     max_level=max_level, eps=eps)

    mesh = Mesh.from_data('linearized_mesh', coors, None, [conn], [mat_ids],
                          field.domain.mesh.descs)

    out = {}
    out[name] = Struct(name='output_data', mode='vertex',
                       data=vdofs, var_name=name, dofs=None,
                       mesh=mesh, level=level)

    out = convert_complex_output(out)

    return out
Example #40
0
    def linearize(self, dofs, min_level=0, max_level=1, eps=1e-4):
        """
        Linearize the solution for post-processing.

        Parameters
        ----------
        dofs : array, shape (n_nod, n_component)
            The array of DOFs reshaped so that each column corresponds
            to one component.
        min_level : int
            The minimum required level of mesh refinement.
        max_level : int
            The maximum level of mesh refinement.
        eps : float
            The relative tolerance parameter of mesh adaptivity.

        Returns
        -------
        mesh : Mesh instance
            The adapted, nonconforming, mesh.
        vdofs : array
            The DOFs defined in vertices of `mesh`.
        levels : array of ints
            The refinement level used for each element group.
        """
        assert_(dofs.ndim == 2)

        n_nod, dpn = dofs.shape

        assert_(n_nod == self.n_nod)
        assert_(dpn == self.shape[0])

        vertex_coors = self.coors[:self.n_vertex_dof, :]

        coors = []
        vdofs = []
        conns = []
        mat_ids = []
        levels = []
        offset = 0
        for ig, ap in self.aps.iteritems():
            ps = ap.interp.poly_spaces['v']
            gps = ap.interp.gel.interp.poly_spaces['v']
            group = self.domain.groups[ig]
            vertex_conn = ap.econn[:, :group.shape.n_ep]

            eval_dofs = get_eval_dofs(dofs, ap.econn, ps, ori=ap.ori)
            eval_coors = get_eval_coors(vertex_coors, vertex_conn, gps)

            (level, _coors, conn,
             _vdofs, _mat_ids) = create_output(eval_dofs, eval_coors,
                                               group.shape.n_el, ps,
                                               min_level=min_level,
                                               max_level=max_level, eps=eps)

            _mat_ids[:] = self.domain.mesh.mat_ids[ig][0]

            coors.append(_coors)
            vdofs.append(_vdofs)
            conns.append(conn + offset)
            mat_ids.append(_mat_ids)
            levels.append(level)

            offset += _coors.shape[0]

        coors = nm.concatenate(coors, axis=0)
        vdofs = nm.concatenate(vdofs, axis=0)
        mesh = Mesh.from_data('linearized_mesh', coors, None, conns, mat_ids,
                              self.domain.mesh.descs)

        return mesh, vdofs, levels
Example #41
0
def gen_cylinder_mesh(dims, shape, centre, axis='x', force_hollow=False,
                      is_open=False, open_angle=0.0, non_uniform=False,
                      name='cylinder', verbose=True):
    """
    Generate a cylindrical mesh along an axis. Its cross-section can be
    ellipsoidal.

    Parameters
    ----------
    dims : array of 5 floats
        Dimensions of the cylinder: inner surface semi-axes a1, b1, outer
        surface semi-axes a2, b2, length.
    shape : array of 3 ints
        Shape (counts of nodes in radial, circumferential and longitudinal
        directions) of the cylinder mesh.
    centre : array of 3 floats
        Centre of the cylinder.
    axis: one of 'x', 'y', 'z'
        The axis of the cylinder.
    force_hollow : boolean
        Force hollow mesh even if inner radii a1 = b1 = 0.
    is_open : boolean
        Generate an open cylinder segment.
    open_angle : float
        Opening angle in radians.
    non_uniform : boolean
        If True, space the mesh nodes in radial direction so that the element
        volumes are (approximately) the same, making thus the elements towards
        the outer surface thinner.
    name : string
        Mesh name.
    verbose : bool
        If True, show progress of the mesh generation.

    Returns
    -------
    mesh : Mesh instance
    """
    dims = nm.asarray(dims, dtype=nm.float64)
    shape = nm.asarray(shape, dtype=nm.int32)
    centre = nm.asarray(centre, dtype=nm.float64)

    a1, b1, a2, b2, length = dims
    nr, nfi, nl = shape
    origin = centre - nm.array([0.5 * length, 0.0, 0.0])

    dfi = 2.0 * (nm.pi - open_angle) / nfi
    if is_open:
        nnfi = nfi + 1
    else:
        nnfi = nfi

    is_hollow = force_hollow or not (max(abs(a1), abs(b1)) < 1e-15)

    if is_hollow:
        mr = 0
    else:
        mr = (nnfi - 1) * nl

    grid = nm.zeros((nr, nnfi, nl), dtype=nm.int32)

    n_nod = nr * nnfi * nl - mr
    coors = nm.zeros((n_nod, 3), dtype=nm.float64)

    angles = nm.linspace(open_angle, open_angle+(nfi)*dfi, nfi+1)
    xs = nm.linspace(0.0, length, nl)
    if non_uniform:
        ras = nm.zeros((nr,), dtype=nm.float64)
        rbs = nm.zeros_like(ras)
        advol = (a2**2 - a1**2) / (nr - 1)
        bdvol = (b2**2 - b1**2) / (nr - 1)
        ras[0], rbs[0] = a1, b1
        for ii in range(1, nr):
            ras[ii] = nm.sqrt(advol + ras[ii-1]**2)
            rbs[ii] = nm.sqrt(bdvol + rbs[ii-1]**2)
    else:
        ras = nm.linspace(a1, a2, nr)
        rbs = nm.linspace(b1, b2, nr)

    # This is 3D only...
    output('generating %d vertices...' % n_nod, verbose=verbose)
    ii = 0
    for ix in range(nr):
        a, b = ras[ix], rbs[ix]
        for iy, fi in enumerate(angles[:nnfi]):
            for iz, x in enumerate(xs):
                grid[ix,iy,iz] = ii
                coors[ii] = origin + [x, a * nm.cos(fi), b * nm.sin(fi)]
                ii += 1

                if not is_hollow and (ix == 0):
                    if iy > 0:
                        grid[ix,iy,iz] = grid[ix,0,iz]
                        ii -= 1
    assert_(ii == n_nod)
    output('...done', verbose=verbose)

    n_el = (nr - 1) * nnfi * (nl - 1)
    conn = nm.zeros((n_el, 8), dtype=nm.int32)

    output('generating %d cells...' % n_el, verbose=verbose)
    ii = 0
    for (ix, iy, iz) in cycle([nr-1, nnfi, nl-1]):
        if iy < (nnfi - 1):
            conn[ii,:] = [grid[ix  ,iy  ,iz  ], grid[ix+1,iy  ,iz  ],
                          grid[ix+1,iy+1,iz  ], grid[ix  ,iy+1,iz  ],
                          grid[ix  ,iy  ,iz+1], grid[ix+1,iy  ,iz+1],
                          grid[ix+1,iy+1,iz+1], grid[ix  ,iy+1,iz+1]]
            ii += 1
        elif not is_open:
            conn[ii,:] = [grid[ix  ,iy  ,iz  ], grid[ix+1,iy  ,iz  ],
                          grid[ix+1,0,iz  ], grid[ix  ,0,iz  ],
                          grid[ix  ,iy  ,iz+1], grid[ix+1,iy  ,iz+1],
                          grid[ix+1,0,iz+1], grid[ix  ,0,iz+1]]
            ii += 1

    mat_id = nm.zeros((n_el,), dtype = nm.int32)
    desc = '3_8'

    assert_(n_nod == (conn.max() + 1))
    output('...done', verbose=verbose)

    if axis == 'z':
        coors = coors[:,[1,2,0]]
    elif axis == 'y':
        coors = coors[:,[2,0,1]]

    mesh = Mesh.from_data(name, coors, None, [conn], [mat_id], [desc])
    return mesh
Example #42
0
def create_expression_output(
    expression,
    name,
    primary_field_name,
    fields,
    materials,
    variables,
    functions=None,
    mode="eval",
    term_mode=None,
    extra_args=None,
    verbose=True,
    kwargs=None,
    min_level=0,
    max_level=1,
    eps=1e-4,
):
    """
    Create output mesh and data for the expression using the adaptive
    linearizer.

    Parameters
    ----------
    expression : str
        The expression to evaluate.
    name : str
        The name of the data.
    primary_field_name : str
        The name of field that defines the element groups and polynomial
        spaces.
    fields : dict
        The dictionary of fields used in `variables`.
    materials : Materials instance
        The materials used in the expression.
    variables : Variables instance
        The variables used in the expression.
    functions : Functions instance, optional
        The user functions for materials etc.
    mode : one of 'eval', 'el_avg', 'qp'
        The evaluation mode - 'qp' requests the values in quadrature points,
        'el_avg' element averages and 'eval' means integration over
        each term region.
    term_mode : str
        The term call mode - some terms support different call modes
        and depending on the call mode different values are
        returned.
    extra_args : dict, optional
        Extra arguments to be passed to terms in the expression.
    verbose : bool
        If False, reduce verbosity.
    kwargs : dict, optional
        The variables (dictionary of (variable name) : (Variable
        instance)) to be used in the expression.
    min_level : int
        The minimum required level of mesh refinement.
    max_level : int
        The maximum level of mesh refinement.
    eps : float
        The relative tolerance parameter of mesh adaptivity.

    Returns
    -------
    out : dict
        The output dictionary.
    """
    field = fields[primary_field_name]
    vertex_coors = field.coors[: field.n_vertex_dof, :]

    coors = []
    vdofs = []
    conns = []
    mat_ids = []
    levels = []
    offset = 0
    for ig, ap in field.aps.iteritems():
        ps = ap.interp.poly_spaces["v"]
        gps = ap.interp.gel.interp.poly_spaces["v"]
        group = field.domain.groups[ig]
        vertex_conn = ap.econn[:, : group.shape.n_ep]

        eval_dofs = get_eval_expression(
            expression,
            ig,
            fields,
            materials,
            variables,
            functions=functions,
            mode=mode,
            extra_args=extra_args,
            verbose=verbose,
            kwargs=kwargs,
        )
        eval_coors = get_eval_coors(vertex_coors, vertex_conn, gps)

        (level, _coors, conn, _vdofs, _mat_ids) = create_output(
            eval_dofs, eval_coors, group.shape.n_el, ps, min_level=min_level, max_level=max_level, eps=eps
        )

        _mat_ids[:] = field.domain.mesh.mat_ids[ig][0]

        coors.append(_coors)
        vdofs.append(_vdofs)
        conns.append(conn + offset)
        mat_ids.append(_mat_ids)
        levels.append(level)

        offset += _coors.shape[0]

    coors = nm.concatenate(coors, axis=0)
    vdofs = nm.concatenate(vdofs, axis=0)
    mesh = Mesh.from_data("linearized_mesh", coors, None, conns, mat_ids, field.domain.mesh.descs)

    out = {}
    out[name] = Struct(
        name="output_data", mode="vertex", data=vdofs, var_name=name, dofs=None, mesh=mesh, levels=levels
    )

    out = convert_complex_output(out)

    return out
def define(filename_mesh=None):
    eps0 = 0.01  # given scale parameter

    if filename_mesh is None:
        filename_mesh = osp.join(data_dir, 'micro_perf_puc.vtk')

    mesh = Mesh.from_file(filename_mesh)

    dim = 3
    sym = (dim + 1) * dim // 2
    sym_eye = 'nm.array([1,1,0])' if dim == 2 else 'nm.array([1,1,1,0,0,0])'

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

    regions.update({
        'Y': 'all',
        'Gamma_Y': ('vertices of surface', 'facet'),
        # solid matrix
        'Ys': 'cells of group 1',
        'Ys_left': ('r.Ys *v r.Left', 'vertex'),
        'Ys_right': ('r.Ys *v r.Right', 'vertex'),
        'Ys_bottom': ('r.Ys *v r.Bottom', 'vertex'),
        'Ys_top': ('r.Ys *v r.Top', 'vertex'),
        'Gamma_Ysf': ('r.Ys *v r.Yf', 'facet', 'Ys'),
        # channel
        'Yf': 'cells of group 2',
        'Yf0': ('r.Yf -v r.Gamma_Yfs', 'vertex'),
        'Yf_left': ('r.Yf0 *v r.Left', 'vertex'),
        'Yf_right': ('r.Yf0 *v r.Right', 'vertex'),
        'Yf_bottom': ('r.Yf0 *v r.Bottom', 'vertex'),
        'Yf_top': ('r.Yf0 *v r.Top', 'vertex'),
        'Gamma_Yfs': ('r.Ys *v r.Yf', 'facet', 'Yf'),
    })

    if dim == 3:
        regions.update({
            'Ys_far': ('r.Ys *v r.Far', 'vertex'),
            'Ys_near': ('r.Ys *v r.Near', 'vertex'),
            'Yf_far': ('r.Yf0 *v r.Far', 'vertex'),
            'Yf_near': ('r.Yf0 *v r.Near', 'vertex'),
        })

    fields = {
        'volume': ('real', 'scalar', 'Y', 1),
        'displacement': ('real', 'vector', 'Ys', 1),
        'pressure': ('real', 'scalar', 'Yf', 1),
        'velocity': ('real', 'vector', 'Yf', 2),
    }

    variables = {
        # displacement
        'u': ('unknown field', 'displacement'),
        'v': ('test field', 'displacement', 'u'),
        'Pi_u': ('parameter field', 'displacement', 'u'),
        'U1': ('parameter field', 'displacement', '(set-to-None)'),
        'U2': ('parameter field', 'displacement', '(set-to-None)'),
        # velocity
        'w': ('unknown field', 'velocity'),
        'z': ('test field', 'velocity', 'w'),
        'Pi_w': ('parameter field', 'velocity', 'w'),
        'W1': ('parameter field', 'velocity', '(set-to-None)'),
        'W2': ('parameter field', 'velocity', '(set-to-None)'),
        # pressure
        'p': ('unknown field', 'pressure'),
        'q': ('test field', 'pressure', 'p'),
        # volume
        'volume': ('parameter field', 'volume', '(set-to-None)'),
    }

    functions = {
        'match_x_plane': (per.match_x_plane, ),
        'match_y_plane': (per.match_y_plane, ),
        'match_z_plane': (per.match_z_plane, ),
    }

    materials = {
        'matrix': ({
            'D': stiffness_from_youngpoisson(dim, 1e3, 0.49)
        }, ),  #Soft tissue
        'fluid': (
            {
                'eta_p': 3.6e-3 / eps0**2,  #Rescaled blood viscosity
                'aux_compress': 1e-18
            }, ),  #Auxillary compressibility
    }

    ebcs = {
        'fixed_u': ('Corners', {
            'u.all': 0.0
        }),
        'fixed_w': ('Gamma_Yfs', {
            'w.all': 0.0
        }),
    }

    epbcs, periodic = get_periodic_bc([('u', 'Ys'), ('p', 'Yf'), ('w', 'Yf')])

    integrals = {
        'i': 4,
    }

    options = {
        'coefs': 'coefs',
        'coefs_filename': 'coefs_micro',
        'requirements': 'requirements',
        'volume': {
            'variables': ['u', 'p'],
            'expression': 'd_volume.i.Ys(u) + d_volume.i.Yf(p)',
        },
        'output_dir': data_dir + '/results/micro',
        'ls': 'ls',
        'file_per_var': True,
        'absolute_mesh_path': True,
        'multiprocessing': True,
        'output_prefix': 'micro:',
    }
    #Definition of used solvers
    solvers = {
        'ls': ('ls.mumps', {}),
        'ns_em9': ('nls.newton', {
            'i_max': 1,
            'eps_a': 1e-9,
            'eps_r': 1e-3,
            'problem': 'nonlinear'
        }),
        'ns_em12': ('nls.newton', {
            'i_max': 1,
            'eps_a': 1e-12,
            'eps_r': 1e-3,
            'problem': 'nonlinear'
        }),
    }
    #Definition of homogenized coefficients, see (22) and (23)
    coefs = {
        #Elasticity coefficient
        'A': {
            'requires': ['pis_u', 'corrs_omega_ij'],
            'expression':
            'dw_lin_elastic.i.Ys(matrix.D, U1, U2)',
            'set_variables': [('U1', ('corrs_omega_ij', 'pis_u'), 'u'),
                              ('U2', ('corrs_omega_ij', 'pis_u'), 'u')],
            'class':
            cb.CoefSymSym,
        },
        #Biot coefficient
        'hat_B': {
            'status': 'auxiliary',
            'requires': ['corrs_omega_ij'],
            'expression': '- ev_div.i.Ys(U1)',
            'set_variables': [('U1', 'corrs_omega_ij', 'u')],
            'class': cb.CoefSym,
        },
        'B': {
            'requires': ['c.phi_f', 'c.hat_B'],
            'expression': 'c.hat_B + c.phi_f * %s' % sym_eye,
            'class': cb.CoefEval,
        },
        'M': {
            'requires': ['corrs_omega_p'],
            'expression':
            'dw_lin_elastic.i.Ys(matrix.D, U1, U2)',
            'set_variables': [('U1', 'corrs_omega_p', 'u'),
                              ('U2', 'corrs_omega_p', 'u')],
            'class':
            cb.CoefOne,
        },
        #Permeability
        'K': {
            'requires': ['corrs_psi_i'],
            'expression':
            'dw_div_grad.i.Yf(W1, W2)',  # !!!
            'set_variables': [('W1', 'corrs_psi_i', 'w'),
                              ('W2', 'corrs_psi_i', 'w')],
            'class':
            cb.CoefDimDim,
        },
        #Volume fraction of fluid part
        'phi_f': {
            'requires': ['c.vol'],
            'expression': 'c.vol["fraction_Yf"]',
            'class': cb.CoefEval,
        },
        #Coefficient for storing viscosity
        'eta_p': {
            'expression': '%e' % materials['fluid'][0]['eta_p'],
            'class': cb.CoefEval,
        },
        #Volume fractions
        'vol': {
            'regions': ['Ys', 'Yf'],
            'expression': 'd_volume.i.%s(volume)',
            'class': cb.VolumeFractions,
        },
        #Surface volume fractions
        'surf_vol': {
            'regions': ['Ys', 'Yf'],
            'expression': 'd_surface.i.%s(volume)',
            'class': cb.VolumeFractions,
        },
        'filenames': {},
    }
    #Definition of microscopic corrector problems
    requirements = {
        #Definition of \Pi^{ij}_k
        'pis_u': {
            'variables': ['u'],
            'class': cb.ShapeDimDim,
        },
        #Correcotr like class returning ones
        'pis_w': {
            'variables': ['w'],
            'class': cb.OnesDim,
        },
        #Corrector problem related to elasticity, see (17)
        'corrs_omega_ij': {
            'requires': ['pis_u'],
            'ebcs': ['fixed_u'],
            'epbcs': periodic['per_u'],
            'is_linear': True,
            'equations': {
                'balance_of_forces':
                    """dw_lin_elastic.i.Ys(matrix.D, v, u)
                   = - dw_lin_elastic.i.Ys(matrix.D, v, Pi_u)"""
            },
            'set_variables': [('Pi_u', 'pis_u', 'u')],
            'class': cb.CorrDimDim,
            'save_name': 'corrs_omega_ij',
            'dump_variables': ['u'],
            'solvers': {'ls': 'ls', 'nls': 'ns_em9'},
        },
        # Corrector problem related to elasticity, see (18)
        'corrs_omega_p': {
            'requires': [],
            'ebcs': ['fixed_u'],
            'epbcs': periodic['per_u'],
            'equations': {
                'balance_of_forces':
                    """dw_lin_elastic.i.Ys(matrix.D, v, u)
                     = -dw_surface_ltr.i.Gamma_Ysf(v)"""
            },
            'class': cb.CorrOne,
            'save_name': 'corrs_omega_p',
            'dump_variables': ['u'],
            'solvers': {'ls': 'ls', 'nls': 'ns_em3'},
        },
        #Corrector problem related to velocity, see (19)
        'corrs_psi_i': {
            'requires': ['pis_w'],
            'ebcs': ['fixed_w'],
             'epbcs': periodic['per_w'] + periodic['per_p'],
            'is_linear': True,
            'equations': {
                'balance_of_forces':  # !!!
                    """dw_div_grad.i.Yf(fluid.eta_p,z, w)
                     - dw_stokes.i.Yf(z, p)
                     = dw_volume_dot.i.Yf(z, Pi_w)""",
                'incompressibility':
                    """dw_stokes.i.Yf(w, q)
                    + dw_volume_dot.i.Yf(fluid.aux_compress, q, p)
                     = 0""",#
            },
            'set_variables': [('Pi_w', 'pis_w', 'w')],
            'class': cb.CorrDim,
            'save_name': 'corrs_psi_i',
            'dump_variables': ['w', 'p'],
            'solvers': {'ls': 'ls', 'nls': 'ns_em12'},
        },
    }

    return locals()
Example #44
0
def define(filename_mesh=None):

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

    mesh = Mesh.from_file(filename_mesh)

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

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

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

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

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

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

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

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

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

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

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

    integrals = {
        'i': 4,
    }

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

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

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

    return locals()
Example #45
0
def gen_mesh_from_voxels(voxels, dims, etype='q'):
    """
    Generate FE mesh from voxels (volumetric data).

    Parameters
    ----------
    voxels : array
        Voxel matrix, 1=material.
    dims : array
        Size of one voxel.
    etype : integer, optional
        'q' - quadrilateral or hexahedral elements
        't' - triangular or tetrahedral elements
    Returns
    -------
    mesh : Mesh instance
        Finite element mesh.
    """

    dims = dims.squeeze()
    dim = len(dims)
    nddims = nm.array(voxels.shape) + 2

    nodemtx = nm.zeros(nddims, dtype=nm.int32)

    if dim == 2:
        #iy, ix = nm.where(voxels.transpose())
        iy, ix = nm.where(voxels)
        nel = ix.shape[0]

        if etype == 'q':
            nodemtx[ix,iy] += 1
            nodemtx[ix + 1,iy] += 1
            nodemtx[ix + 1,iy + 1] += 1
            nodemtx[ix,iy + 1] += 1

        elif etype == 't':
            nodemtx[ix,iy] += 2
            nodemtx[ix + 1,iy] += 1
            nodemtx[ix + 1,iy + 1] += 2
            nodemtx[ix,iy + 1] += 1
            nel *= 2

    elif dim == 3:
        #iy, ix, iz = nm.where(voxels.transpose(1, 0, 2))
        iy, ix, iz = nm.where(voxels)
        nel = ix.shape[0]

        if etype == 'q':
            nodemtx[ix,iy,iz] += 1
            nodemtx[ix + 1,iy,iz] += 1
            nodemtx[ix + 1,iy + 1,iz] += 1
            nodemtx[ix,iy + 1,iz] += 1
            nodemtx[ix,iy,iz + 1] += 1
            nodemtx[ix + 1,iy,iz + 1] += 1
            nodemtx[ix + 1,iy + 1,iz + 1] += 1
            nodemtx[ix,iy + 1,iz + 1] += 1

        elif etype == 't':
            nodemtx[ix,iy,iz] += 6
            nodemtx[ix + 1,iy,iz] += 2
            nodemtx[ix + 1,iy + 1,iz] += 2
            nodemtx[ix,iy + 1,iz] += 2
            nodemtx[ix,iy,iz + 1] += 2
            nodemtx[ix + 1,iy,iz + 1] += 2
            nodemtx[ix + 1,iy + 1,iz + 1] += 6
            nodemtx[ix,iy + 1,iz + 1] += 2
            nel *= 6

    else:
        msg = 'incorrect voxel dimension! (%d)' % dim
        raise ValueError(msg)

    ndidx = nm.where(nodemtx)
    coors = nm.array(ndidx).transpose() * dims
    nnod = coors.shape[0]

    nodeid = -nm.ones(nddims, dtype=nm.int32)
    nodeid[ndidx] = nm.arange(nnod)

    # generate elements
    if dim == 2:
        elems = nm.array([nodeid[ix,iy],
                          nodeid[ix + 1,iy],
                          nodeid[ix + 1,iy + 1],
                          nodeid[ix,iy + 1]]).transpose()

    elif dim == 3:
        elems = nm.array([nodeid[ix,iy,iz],
                          nodeid[ix + 1,iy,iz],
                          nodeid[ix + 1,iy + 1,iz],
                          nodeid[ix,iy + 1,iz],
                          nodeid[ix,iy,iz + 1],
                          nodeid[ix + 1,iy,iz + 1],
                          nodeid[ix + 1,iy + 1,iz + 1],
                          nodeid[ix,iy + 1,iz + 1]]).transpose()

    if etype == 't':
        elems = elems_q2t(elems)

    eid = etype + str(dim)
    eltab = {'q2': 4, 'q3': 8, 't2': 3, 't3': 4}

    mesh = Mesh.from_data('voxel_data',
                          coors, nm.ones((nnod,), dtype=nm.int32),
                          {0: nm.ascontiguousarray(elems)},
                          {0: nm.ones((nel,), dtype=nm.int32)},
                          {0: '%d_%d' % (dim, eltab[eid])})

    return mesh
Example #46
0
def extract_time_history(filename, extract, verbose=True):
    """Extract time history of a variable from a multi-time-step results file.

    Parameters
    ----------
    filename : str
        The name of file to extract from.
    extract : str
        The description of what to extract in a string of comma-separated
        description items. A description item consists of: name of the variable
        to extract, mode ('e' for elements, 'n' for nodes), ids of the nodes or
        elements (given by the mode). Example: 'u n 10 15, p e 0' means
        variable 'u' in nodes 10, 15 and variable 'p' in element 0.
    verbose : bool
        Verbosity control.

    Returns
    -------
    ths : dict
        The time histories in a dict with variable names as keys. If a
        nodal variable is requested in elements, its value is a dict of histories
        in the element nodes.
    ts : TimeStepper instance
        The time stepping information.
    """
    output('extracting selected data...', verbose=verbose)

    output('selection:', extract, verbose=verbose)

    ##
    # Parse extractions.
    pes = OneTypeList(Struct)
    for chunk in extract.split(','):
        aux = chunk.strip().split()
        pes.append(Struct(var = aux[0],
                          mode = aux[1],
                          indx = map(int, aux[2:]),
                          igs = None))

    ##
    # Verify array limits, set igs for element data, shift indx.
    mesh = Mesh.from_file(filename)
    n_el, n_els, offs = mesh.n_el, mesh.n_els, mesh.el_offsets
    for pe in pes:
        if pe.mode == 'n':
            for ii in pe.indx:
                if (ii < 0) or (ii >= mesh.n_nod):
                    raise ValueError('node index 0 <= %d < %d!'
                                     % (ii, mesh.n_nod))

        if pe.mode == 'e':
            pe.igs = []
            for ii, ie in enumerate(pe.indx[:]):
                if (ie < 0) or (ie >= n_el):
                    raise ValueError('element index 0 <= %d < %d!'
                                     % (ie, n_el))
                ig = (ie < n_els).argmax()
                pe.igs.append(ig)
                pe.indx[ii] = ie - offs[ig]

##     print pes

    ##
    # Extract data.
    # Assumes only one element group (ignores igs)!
    io = MeshIO.any_from_filename(filename)
    ths = {}
    for pe in pes:
        mode, nname = io.read_data_header(pe.var)
        output(mode, nname, verbose=verbose)

        if ((pe.mode == 'n' and mode == 'vertex') or
            (pe.mode == 'e' and mode == 'cell')):
            th = io.read_time_history(nname, pe.indx)

        elif pe.mode == 'e' and mode == 'vertex':
            conn = mesh.conns[0]
            th = {}
            for iel in pe.indx:
                ips = conn[iel]
                th[iel] = io.read_time_history(nname, ips)
        else:
            raise ValueError('cannot extract cell data %s in nodes!' % pe.var)
            
        ths[pe.var] = th

    output('...done', verbose=verbose)

    ts = TimeStepper(*io.read_time_stepper())

    return ths, ts
Example #47
0
def create_expression_output(expression, name, primary_field_name,
                             fields, materials, variables,
                             functions=None, mode='eval', term_mode=None,
                             extra_args=None, verbose=True, kwargs=None,
                             min_level=0, max_level=1, eps=1e-4):
    """
    Create output mesh and data for the expression using the adaptive
    linearizer.

    Parameters
    ----------
    expression : str
        The expression to evaluate.
    name : str
        The name of the data.
    primary_field_name : str
        The name of field that defines the element groups and polynomial
        spaces.
    fields : dict
        The dictionary of fields used in `variables`.
    materials : Materials instance
        The materials used in the expression.
    variables : Variables instance
        The variables used in the expression.
    functions : Functions instance, optional
        The user functions for materials etc.
    mode : one of 'eval', 'el_avg', 'qp'
        The evaluation mode - 'qp' requests the values in quadrature points,
        'el_avg' element averages and 'eval' means integration over
        each term region.
    term_mode : str
        The term call mode - some terms support different call modes
        and depending on the call mode different values are
        returned.
    extra_args : dict, optional
        Extra arguments to be passed to terms in the expression.
    verbose : bool
        If False, reduce verbosity.
    kwargs : dict, optional
        The variables (dictionary of (variable name) : (Variable
        instance)) to be used in the expression.
    min_level : int
        The minimum required level of mesh refinement.
    max_level : int
        The maximum level of mesh refinement.
    eps : float
        The relative tolerance parameter of mesh adaptivity.

    Returns
    -------
    out : dict
        The output dictionary.
    """
    field = fields[primary_field_name]
    vertex_coors = field.coors[:field.n_vertex_dof, :]

    coors = []
    vdofs = []
    conns = []
    mat_ids = []
    levels = []
    offset = 0
    for ig, ap in field.aps.iteritems():
        ps = ap.interp.poly_spaces['v']
        gps = ap.interp.gel.interp.poly_spaces['v']
        group = field.domain.groups[ig]
        vertex_conn = ap.econn[:, :group.shape.n_ep]

        eval_dofs = get_eval_expression(expression, ig,
                                        fields, materials, variables,
                                        functions=functions,
                                        mode=mode, extra_args=extra_args,
                                        verbose=verbose, kwargs=kwargs)
        eval_coors = get_eval_coors(vertex_coors, vertex_conn, gps)

        (level, _coors, conn,
         _vdofs, _mat_ids) = create_output(eval_dofs, eval_coors,
                                           group.shape.n_el, ps,
                                           min_level=min_level,
                                           max_level=max_level, eps=eps)

        _mat_ids[:] = field.domain.mesh.mat_ids[ig][0]

        coors.append(_coors)
        vdofs.append(_vdofs)
        conns.append(conn + offset)
        mat_ids.append(_mat_ids)
        levels.append(level)

        offset += _coors.shape[0]

    coors = nm.concatenate(coors, axis=0)
    vdofs = nm.concatenate(vdofs, axis=0)
    mesh = Mesh.from_data('linearized_mesh', coors, None, conns, mat_ids,
                          field.domain.mesh.descs)

    out = {}
    out[name] = Struct(name='output_data', mode='vertex',
                       data=vdofs, var_name=name, dofs=None,
                       mesh=mesh, levels=levels)

    out = convert_complex_output(out)

    return out
Example #48
0
def dump_to_vtk(filename, output_filename_trunk=None, step0=0, steps=None,
                fields=None, linearization=None):
    """Dump a multi-time-step results file into a sequence of VTK files."""
    def _save_step(suffix, out, mesh):
        if linearization is not None:
            output('linearizing...')
            out = _linearize(out, fields, linearization)
            output('...done')
            for key, val in out.iteritems():
                lmesh = val.get('mesh', mesh)
                lmesh.write(output_filename_trunk + '_' + key + suffix,
                            io='auto', out={key : val})
                if hasattr(val, 'levels'):
                    output('max. refinement per group:', val.levels)

        else:
            mesh.write(output_filename_trunk + suffix, io='auto', out=out)

    output('dumping to VTK...')

    io = MeshIO.any_from_filename(filename)
    mesh = Mesh.from_file(filename, io=io)

    if output_filename_trunk is None:
        output_filename_trunk = get_trunk(filename)

    try:
        ts = TimeStepper(*io.read_time_stepper())
        all_steps, times, nts, dts = extract_times(filename)

    except ValueError:
        output('no time stepping info found, assuming single step')

        out = io.read_data(0)
        if out is not None:
            _save_step('.vtk', out, mesh)

        ret = None

    else:
        ts.times = times
        ts.n_step = times.shape[0]

        if steps is None:
            ii0 = nm.searchsorted(all_steps, step0)
            iterator = ((all_steps[ii], times[ii])
                        for ii in xrange(ii0, len(times)))

        else:
            iterator = [(step, ts.times[step]) for step in steps]

        max_step = all_steps.max()
        for step, time in iterator:
            output(ts.format % (step, max_step))
            out = io.read_data(step)
            if out is None: break

            _save_step('.' + ts.suffix % step + '.vtk', out, mesh)

        ret = ts.suffix

    output('...done')
    return ret
Example #49
0
def main():
    parser = OptionParser(usage=usage, version='%prog ' + sfepy.__version__)
    parser.add_option('-c', '--conf', metavar='"key : value, ..."',
                      action='store', dest='conf', type='string',
                      default=None, help= help['conf'])
    parser.add_option('-O', '--options', metavar='"key : value, ..."',
                      action='store', dest='app_options', type='string',
                      default=None, help=help['options'])
    parser.add_option('-o', '', metavar='filename',
                      action='store', dest='output_filename_trunk',
                      default=None, help=help['filename'])
    parser.add_option('--create-mesh',
                      action='store_true', dest='create_mesh',
                      default=False, help=help['create_mesh'])
    parser.add_option('--2d',
                      action='store_true', dest='dim2',
                      default=False, help=help['dim'])
    parser.add_option('-m', '--mesh', metavar='filename',
                      action='store', dest='mesh',
                      default=None, help=help['mesh'])
    parser.add_option('--mesh-dir', metavar='dirname',
                      action='store', dest='mesh_dir',
                      default='tmp', help=help['mesh_dir'])
    parser.add_option('--oscillator',
                      action='store_true', dest='oscillator',
                      default=False, help=help['oscillator'])
    parser.add_option('--well',
                      action='store_true', dest='well',
                      default=False, help=help['well'])
    parser.add_option('--hydrogen',
                      action='store_true', dest='hydrogen',
                      default=False, help=help['hydrogen'])
    parser.add_option('--boron',
                      action='store_true', dest='boron',
                      default=False, help=help['boron'])

    options, args = parser.parse_args()

    if options.create_mesh and options.mesh:
        output('--create-mesh and --mesh options are mutually exclusive!')
        return

    if len(args) == 1:
        filename_in = args[0];
        auto_mesh_name = False

    elif len(args) == 0:
        auto_mesh_name = True

        mesh_filename = os.path.join(options.mesh_dir, 'mesh.vtk')
        ensure_path(mesh_filename)

        if options.oscillator:
            filename_in = fix_path("examples/quantum/oscillator.py")

        elif options.well:
            filename_in = fix_path("examples/quantum/well.py")

        elif options.hydrogen:
            filename_in = fix_path("examples/quantum/hydrogen.py")

        elif options.boron:
            filename_in = fix_path("examples/quantum/boron.py")

        elif options.create_mesh:
            output('generating mesh...')
            try:
                os.makedirs("tmp")
            except OSError, e:
                if e.errno != 17: # [Errno 17] File exists
                    raise
            if options.dim2:
                output("dimension: 2")
                gp = fix_path('meshes/quantum/square.geo')
                os.system("cp %s tmp/mesh.geo" % gp)
                os.system("gmsh -2 tmp/mesh.geo -format mesh")
                mtv = fix_path('script/convert_mesh.py')
                os.system("%s tmp/mesh.mesh %s" % (mtv, mesh_filename))
            else:
                output("dimension: 3")
                import sfepy.mesh as geom
                from sfepy.discrete.fem.mesh import Mesh
                try:
                    from site_cfg import tetgen_path
                except ImportError:
                    tetgen_path = '/usr/bin/tetgen'
                gp = fix_path('meshes/quantum/box.geo')
                os.system("gmsh -0 %s -o tmp/x.geo" % gp)
                g = geom.read_gmsh("tmp/x.geo")
                g.printinfo()
                geom.write_tetgen(g, "tmp/t.poly")
                geom.runtetgen("tmp/t.poly", a=0.03, Q=1.0,
                               quadratic=False, tetgenpath=tetgen_path)
                m = Mesh.from_file("tmp/t.1.node")
                m.write(mesh_filename, io="auto")
            output("...mesh written to %s" % mesh_filename)
            return

        else:
            parser.print_help()
            return
Example #50
0
def define(is_opt=False):
    filename_mesh = data_dir + '/meshes/3d/matrix_fiber_rand.vtk'

    mesh = Mesh.from_file(filename_mesh)
    bbox = mesh.get_bounding_box()

    regions = {
        'Y': 'all',
        'Ym': ('cells of group 7', 'cell'),
        'Yf': ('r.Y -c r.Ym', 'cell'),
    }

    regions.update(define_box_regions(3, bbox[0], bbox[1]))

    functions = {
        'get_mat':
        (lambda ts, coors, mode=None, problem=None, **kwargs: get_mat(
            coors, mode, problem),
         ),
        'match_x_plane': (per.match_x_plane, ),
        'match_y_plane': (per.match_y_plane, ),
        'match_z_plane': (per.match_z_plane, ),
    }

    materials = {
        'mat': 'get_mat',
    }

    fields = {
        'corrector': ('real', 3, 'Y', 1),
    }

    variables = {
        'u': ('unknown field', 'corrector'),
        'v': ('test field', 'corrector', 'u'),
        'Pi': ('parameter field', 'corrector', 'u'),
        'Pi1': ('parameter field', 'corrector', '(set-to-None)'),
        'Pi2': ('parameter field', 'corrector', '(set-to-None)'),
    }

    ebcs = {
        'fixed_u': ('Corners', {
            'u.all': 0.0
        }),
    }

    epbcs = {
        'periodic_x': (['Left', 'Right'], {
            'u.all': 'u.all'
        }, 'match_x_plane'),
        'periodic_y': (['Near', 'Far'], {
            'u.all': 'u.all'
        }, 'match_y_plane'),
        'periodic_z': (['Top', 'Bottom'], {
            'u.all': 'u.all'
        }, 'match_z_plane'),
    }

    all_periodic = ['periodic_%s' % ii for ii in ['x', 'y', 'z'][:3]]

    options = {
        'coefs': 'coefs',
        'requirements': 'requirements',
        'volume': {
            'variables': ['u'],
            'expression': 'ev_volume.5.Y( u )'
        },
        'output_dir': 'output',
        'coefs_filename': 'coefs_le',
    }

    equation_corrs = {
        'balance_of_forces':
        """dw_lin_elastic.5.Y(mat.D, v, u)
                = - dw_lin_elastic.5.Y(mat.D, v, Pi)"""
    }

    coefs = {
        'D': {
            'requires': ['pis', 'corrs_rs'],
            'expression':
            'dw_lin_elastic.5.Y(mat.D, Pi1, Pi2 )',
            'set_variables': [('Pi1', ('pis', 'corrs_rs'), 'u'),
                              ('Pi2', ('pis', 'corrs_rs'), 'u')],
            'class':
            cb.CoefSymSym,
        },
        'vol': {
            'regions': ['Ym', 'Yf'],
            'expression': 'ev_volume.5.%s(u)',
            'class': cb.VolumeFractions,
        },
        'filenames': {},
    }

    requirements = {
        'pis': {
            'variables': ['u'],
            'class': cb.ShapeDimDim,
        },
        'corrs_rs': {
            'requires': ['pis'],
            'ebcs': ['fixed_u'],
            'epbcs': all_periodic,
            'equations': equation_corrs,
            'set_variables': [('Pi', 'pis', 'u')],
            'class': cb.CorrDimDim,
            'save_name': 'corrs_le',
        },
    }

    solvers = {
        'ls': ('ls.scipy_direct', {}),
        'newton': ('nls.newton', {
            'i_max': 1,
            'eps_a': 1e-4,
            'problem': 'linear',
        })
    }

    if is_opt:
        options.update({
            'parametric_hook': 'optimization_hook',
            'float_format': '%.16e',
        })

    return locals()
Example #51
0
def gen_tiled_mesh(mesh, grid=None, scale=1.0, eps=1e-6, ret_ndmap=False):
    """
    Generate a new mesh by repeating a given periodic element
    along each axis.

    Parameters
    ----------
    mesh : Mesh instance
        The input periodic FE mesh.
    grid : array
        Number of repetition along each axis.
    scale : float, optional
        Scaling factor.
    eps : float, optional
        Tolerance for boundary detection.
    ret_ndmap : bool, optional
        If True, return global node map.

    Returns
    -------
    mesh_out : Mesh instance
        FE mesh.
    ndmap : array
        Maps: actual node id --> node id in the reference cell.
    """
    bbox = mesh.get_bounding_box()

    if grid is None:
        iscale = max(int(1.0 / scale), 1)
        grid = [iscale] * mesh.dim

    conn = mesh.get_conn(mesh.descs[0])
    mat_ids = mesh.cmesh.cell_groups

    coors = mesh.coors
    ngrps = mesh.cmesh.vertex_groups
    nrep = nm.prod(grid)
    ndmap = None

    output('repeating %s ...' % grid)
    nblk = 1
    for ii, gr in enumerate(grid):
        if ret_ndmap:
            (conn, coors,
             ngrps, ndmap0) = tiled_mesh1d(conn, coors, ngrps,
                                           ii, gr, bbox.transpose()[ii],
                                           eps=eps, ndmap=ndmap)
            ndmap = ndmap0

        else:
            conn, coors, ngrps = tiled_mesh1d(conn, coors, ngrps,
                                              ii, gr, bbox.transpose()[ii],
                                              eps=eps)
        nblk *= gr

    output('...done')

    mat_ids = nm.tile(mat_ids, (nrep,))
    mesh_out = Mesh.from_data('tiled mesh', coors * scale, ngrps,
                              [conn], [mat_ids], [mesh.descs[0]])

    if ret_ndmap:
        return mesh_out, ndmap
    else:
        return mesh_out
Example #52
0
def define(is_opt=False):
    filename_mesh = data_dir + '/meshes/3d/matrix_fiber_rand.vtk'

    mesh = Mesh.from_file(filename_mesh)
    bbox = mesh.get_bounding_box()

    regions = {
        'Y' : 'all',
        'Ym' : ('cells of group 7', 'cell'),
        'Yf' : ('r.Y -c r.Ym', 'cell'),
    }

    regions.update(define_box_regions(3, bbox[0], bbox[1]))

    functions = {
        'get_mat': (lambda ts, coors, mode=None, problem=None, **kwargs:
                    get_mat(coors, mode, problem),),
        'match_x_plane' : (per.match_x_plane,),
        'match_y_plane' : (per.match_y_plane,),
        'match_z_plane' : (per.match_z_plane,),
    }

    materials = {
        'mat': 'get_mat',
    }

    fields = {
        'corrector' : ('real', 3, 'Y', 1),
    }

    variables = {
        'u': ('unknown field', 'corrector'),
        'v': ('test field', 'corrector', 'u'),
        'Pi': ('parameter field', 'corrector', 'u'),
        'Pi1': ('parameter field', 'corrector', '(set-to-None)'),
        'Pi2': ('parameter field', 'corrector', '(set-to-None)'),
    }

    ebcs = {
        'fixed_u' : ('Corners', {'u.all' : 0.0}),
    }

    epbcs = {
        'periodic_x' : (['Left', 'Right'], {'u.all' : 'u.all'}, 'match_x_plane'),
        'periodic_y' : (['Near', 'Far'], {'u.all' : 'u.all'}, 'match_y_plane'),
        'periodic_z' : (['Top', 'Bottom'], {'u.all' : 'u.all'}, 'match_z_plane'),
    }

    all_periodic = ['periodic_%s' % ii for ii in ['x', 'y', 'z'][:3]]

    options = {
        'coefs': 'coefs',
        'requirements': 'requirements',
        'volume': { 'variables' : ['u'], 'expression' : 'd_volume.5.Y( u )' },
        'output_dir': 'output',
        'coefs_filename': 'coefs_le',
    }

    equation_corrs = {
        'balance_of_forces':
            """dw_lin_elastic.5.Y(mat.D, v, u)
                = - dw_lin_elastic.5.Y(mat.D, v, Pi)"""
    }

    coefs = {
        'D' : {
            'requires' : ['pis', 'corrs_rs'],
            'expression' : 'dw_lin_elastic.5.Y(mat.D, Pi1, Pi2 )',
            'set_variables': [('Pi1', ('pis', 'corrs_rs'), 'u'),
                              ('Pi2', ('pis', 'corrs_rs'), 'u')],
            'class' : cb.CoefSymSym,
        },
        'vol': {
            'regions': ['Ym', 'Yf'],
            'expression': 'd_volume.5.%s(u)',
            'class': cb.VolumeFractions,
            },
        'filenames' : {},
    }

    requirements = {
        'pis' : {
            'variables' : ['u'],
            'class' : cb.ShapeDimDim,
        },
        'corrs_rs' : {
            'requires' : ['pis'],
            'ebcs' : ['fixed_u'],
            'epbcs' : all_periodic,
            'equations' : equation_corrs,
            'set_variables' : [('Pi', 'pis', 'u')],
            'class' : cb.CorrDimDim,
            'save_name' : 'corrs_le',
        },
    }

    solvers = {
        'ls' : ('ls.scipy_direct', {}),
        'newton' : ('nls.newton', {
            'i_max' : 1,
            'eps_a' : 1e-4,
            'problem': 'linear',
        })
    }

    if is_opt:
        options.update({
            'parametric_hook': 'optimization_hook',
            'float_format': '%.16e',
        })

    return locals()
Example #53
0
def load_1D_vtks(fold, name):
    """Reads series of .vtk files and crunches them into form
    suitable for plot10_DG_sol.
    
    Attempts to read modal cell data for variable mod_data. i.e.
    
    ``?_modal{i}``, where i is number of modal DOF
    
    Resulting solution data have shape:
    ``(order, nspace_steps, ntime_steps, 1)``

    Parameters
    ----------
    fold :
        folder where to look for files
    name :
        used in ``{name}.i.vtk, i = 0,1, ... tns - 1``

    Returns
    -------
    coors : ndarray
    mod_data : ndarray
        solution data

    """

    files = glob(pjoin(fold, name) + ".[0-9]*")

    if len(files) == 0: # no multiple time steps, try loading single file
        print("No files {} found in {}".format(pjoin(fold, name) + ".[0-9]*", fold))
        print("Trying {}".format(pjoin(fold, name) + ".vtk"))
        files = glob(pjoin(fold, name) + ".vtk")
        if files:
            return load_state_1D_vtk(files[0])
        else:
            print("Nothing found.")
            return

    io = MeshioLibIO(files[0])
    coors = io.read(Mesh()).coors[:, 0, None]
    data = io.read_data(step=0)
    var_name = head([k for k in data.keys() if "_modal" in k])[:-1]
    if var_name is None:
        print("File {} does not contain modal data.".format(files[0]))
        return
    porder = len([k for k in data.keys() if var_name in k])

    tn = len(files)
    nts = sorted([int(f.split(".")[-2]) for f in files])

    digs = len(files[0].split(".")[-2])
    full_name_form = ".".join((pjoin(fold, name), ("{:0" + str(digs) + "d}"), "vtk"))

    mod_data = nm.zeros((porder, coors.shape[0] - 1, tn, 1))
    for i, nt in enumerate(nts):
        io = MeshioLibIO(full_name_form.format(nt))
        # parameter "step" does nothing, but is obligatory
        data = io.read_data(step=0)
        for ii in range(porder):
            mod_data[ii, :, i, 0] = data[var_name+'{}'.format(ii)].data

    return coors, mod_data
Example #54
0
def define(eps0=1e-3, filename_mesh='meshes/3d/piezo_mesh_micro.vtk'):

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

    regions.update({
        'Ymc': 'all',
        # matrix
        'Ym': 'cells of group 1',
        'Ym_left': ('r.Ym *v r.Left', 'vertex'),
        'Ym_right': ('r.Ym *v r.Right', 'vertex'),
        'Ym_bottom': ('r.Ym *v r.Bottom', 'vertex'),
        'Ym_top': ('r.Ym *v r.Top', 'vertex'),
        'Ym_far': ('r.Ym *v r.Far', 'vertex'),
        'Ym_near': ('r.Ym *v r.Near', 'vertex'),
        'Gamma_ms': ('r.Ym *v r.Yc', 'facet', 'Ym'),
        # conductors
        'Yc': ('r.Yc1 +c r.Yc2', 'cell'),
        'Yc1': 'cells of group 2',
        'Yc2': 'cells of group 3',
        'Gamma_s1': ('r.Ym *v r.Yc1', 'facet', 'Ym'),
        'Gamma_s2': ('r.Ym *v r.Yc2', 'facet', 'Ym'),
    })

    options = {
        'coefs_filename': 'coefs_piezo',
        'volume': {'value': nm.prod(bbox[1] - bbox[0])},
        'coefs': 'coefs',
        'requirements': 'requirements',
        'output_dir': 'output',
        'file_per_var': True,
        'absolute_mesh_path': True,
        'multiprocessing': False,
        'recovery_hook': recovery_micro,
    }

    fields = {
        'displacement': ('real', 'vector', 'Ymc', 1),
        'potential': ('real', 'scalar', 'Ym', 1),
        'sfield': ('real', 'scalar', 'Ymc', 1),
    }

    variables = {
        # displacement
        'u': ('unknown field', 'displacement'),
        'v': ('test field', 'displacement', 'u'),
        'Pi_u': ('parameter field', 'displacement', 'u'),
        'U1': ('parameter field', 'displacement', '(set-to-None)'),
        'U2': ('parameter field', 'displacement', '(set-to-None)'),
        # potential
        'r': ('unknown field', 'potential'),
        's': ('test field', 'potential', 'r'),
        'Pi_r': ('parameter field', 'potential', 'r'),
        'R1': ('parameter field', 'potential', '(set-to-None)'),
        'R2': ('parameter field', 'potential', '(set-to-None)'),
        # auxiliary
        'svar': ('parameter field', 'sfield', '(set-to-None)'),
    }

    epbcs = {
        'p_ux': (['Left', 'Right'], {'u.all': 'u.all'}, 'match_x_plane'),
        'p_uy': (['Near', 'Far'], {'u.all': 'u.all'}, 'match_y_plane'),
        'p_uz': (['Bottom', 'Top'], {'u.all': 'u.all'}, 'match_z_plane'),
        'p_rx': (['Ym_left', 'Ym_right'], {'r.0': 'r.0'}, 'match_x_plane'),
        'p_ry': (['Ym_near', 'Ym_far'], {'r.0': 'r.0'}, 'match_y_plane'),
        'p_rz': (['Ym_bottom', 'Ym_top'], {'r.0': 'r.0'}, 'match_z_plane'),
    }

    periodic = {
        'per_u': ['per_u_x', 'per_u_y', 'per_u_z'],
        'per_r': ['per_r_x', 'per_r_y', 'per_r_z'],
    }

    # rescale piezoelectric material parameters
    mat_g_sc, mat_d_sc = (eps0, eps0**2)

    materials = {
        'elastic': ({
            'D': {
                'Ym': nm.array([[1.504, 0.656, 0.659, 0, 0, 0],
                                [0.656, 1.504, 0.659, 0, 0, 0],
                                [0.659, 0.659, 1.455, 0, 0, 0],
                                [0, 0, 0, 0.424, 0, 0],
                                [0, 0, 0, 0, 0.439, 0],
                                [0, 0, 0, 0, 0, 0.439]]) * 1e11,
                'Yc': stiffness_from_youngpoisson(3, 200e9, 0.25)}},),
        'piezo': ({
            'g': nm.array([[0, 0, 0, 0, 11.404, 0],
                           [0, 0, 0, 0, 0, 11.404],
                           [-4.322, -4.322, 17.360, 0, 0, 0]]) / mat_g_sc,
            'd': nm.array([[1.284, 0, 0],
                           [0, 1.284, 0],
                           [0, 0, 1.505]]) * 1e-8 / mat_d_sc},),
    }

    functions = {
        'match_x_plane': (per.match_x_plane,),
        'match_y_plane': (per.match_y_plane,),
        'match_z_plane': (per.match_z_plane,),
    }

    ebcs = {
        'fixed_u': ('Corners', {'u.all': 0.0}),
        'fixed_r': ('Gamma_ms', {'r.all': 0.0}),
        'fixed_r1_s1': ('Gamma_s1', {'r.0': 1.0}),
        'fixed_r0_s1': ('Gamma_s1', {'r.0': 0.0}),
        'fixed_r1_s2': ('Gamma_s2', {'r.0': 1.0}),
        'fixed_r0_s2': ('Gamma_s2', {'r.0': 0.0}),
    }

    integrals = {
        'i2': 2,
    }

    solvers = {
        'ls_d': ('ls.scipy_direct', {}),
        'ls_i': ('ls.scipy_iterative', {}),
        'ns_ea6': ('nls.newton', {'eps_a': 1e6, 'eps_r': 1e-3,}),
        'ns_ea0': ('nls.newton', {'eps_a': 1e0, 'eps_r': 1e-3,}),
    }

    coefs = {
        'A1': {
            'status': 'auxiliary',
            'requires': ['pis_u', 'corrs_rs'],
            'expression': 'dw_lin_elastic.i2.Ymc(elastic.D, U1, U2)',
            'set_variables': [('U1', ('corrs_rs', 'pis_u'), 'u'),
                              ('U2', ('corrs_rs', 'pis_u'), 'u')],
            'class': cb.CoefSymSym,
        },
        'A2': {
            'status': 'auxiliary',
            'requires': ['corrs_rs'],
            'expression': 'dw_diffusion.i2.Ym(piezo.d, R1, R2)',
            'set_variables': [('R1', 'corrs_rs', 'r'),
                              ('R2', 'corrs_rs', 'r')],
            'class': cb.CoefSymSym,
        },
        'A': {
            'requires': ['c.A1', 'c.A2'],
            'expression': 'c.A1 + c.A2',
            'class': cb.CoefEval,
        },
        'vol': {
            'regions': ['Ym', 'Yc1', 'Yc2'],
            'expression': 'd_volume.i2.%s(svar)',
            'class': cb.VolumeFractions,
        },
        'eps0': {
            'requires': [],
            'expression': '%e' % eps0,
            'class': cb.CoefEval,
        },
        'filenames': {},
    }

    requirements = {
        'pis_u': {
            'variables': ['u'],
            'class': cb.ShapeDimDim,
        },
        'pis_r': {
            'variables': ['r'],
            'class': cb.ShapeDim,
        },
        'corrs_rs': {
            'requires': ['pis_u'],
            'ebcs': ['fixed_u', 'fixed_r'],
            'epbcs': ['p_ux', 'p_uy', 'p_uz', 'p_rx', 'p_ry', 'p_rz'],
            'equations': {
                'eq1':
                    """dw_lin_elastic.i2.Ymc(elastic.D, v, u)
                     - dw_piezo_coupling.i2.Ym(piezo.g, v, r)
                   = - dw_lin_elastic.i2.Ymc(elastic.D, v, Pi_u)""",
                'eq2':
                    """
                     - dw_piezo_coupling.i2.Ym(piezo.g, u, s)
                     - dw_diffusion.i2.Ym(piezo.d, s, r)
                     = dw_piezo_coupling.i2.Ym(piezo.g, Pi_u, s)""",
            },
            'set_variables': [('Pi_u', 'pis_u', 'u')],
            'class': cb.CorrDimDim,
            'save_name': 'corrs_rs',
            'solvers': {'ls': 'ls_i', 'nls': 'ns_ea6'},
        },
    }

    # define requirements and coefficients related to conductors
    bc_conductors = [
        ['fixed_r1_s1', 'fixed_r0_s2'],  # phi = 1 on S1, phi = 0 on S2
        ['fixed_r1_s2', 'fixed_r0_s1'],  # phi = 0 on S1, phi = 1 on S2
    ]

    for k in range(2):
        sk = '%d' % k

        requirements.update({
            'corrs_k' + sk: {
                'requires': ['pis_r'],
                'ebcs': ['fixed_u'] + bc_conductors[k],
                'epbcs': ['p_ux', 'p_uy', 'p_uz', 'p_rx', 'p_ry', 'p_rz'],
                'equations': {
                    'eq1':
                        """dw_lin_elastic.i2.Ymc(elastic.D, v, u)
                         - dw_piezo_coupling.i2.Ym(piezo.g, v, r)
                         = 0""",
                    'eq2':
                        """
                         - dw_piezo_coupling.i2.Ym(piezo.g, u, s)
                         - dw_diffusion.i2.Ym(piezo.d, s, r)
                         = 0"""
                },
                'class': cb.CorrOne,
                'save_name': 'corrs_k' + sk,
                'solvers': {'ls': 'ls_d', 'nls': 'ns_ea0'},
            },
        })

        coefs.update({
            'V1_' + sk: {
                'status': 'auxiliary',
                'requires': ['pis_u', 'corrs_k' + sk],
                'expression': 'dw_lin_elastic.i2.Ymc(elastic.D, U1, U2)',
                'set_variables': [('U1', 'corrs_k' + sk, 'u'),
                                  ('U2', 'pis_u', 'u')],
                'class': cb.CoefSym,
            },
            'V2_' + sk: {
                'status': 'auxiliary',
                'requires': ['pis_u', 'corrs_k' + sk],
                'expression': 'dw_piezo_coupling.i2.Ym(piezo.g, U1, R1)',
                'set_variables': [('R1', 'corrs_k' + sk, 'r'),
                                  ('U1', 'pis_u', 'u')],
                'class': cb.CoefSym,
            },
            'V' + sk: {
                'requires': ['c.V1_' + sk, 'c.V2_' + sk],
                'expression': 'c.V1_%s - c.V2_%s' % (sk, sk),
                'class': cb.CoefEval,
            },
        })

    return locals()