⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monomialtabulation.py

📁 finite element library for mathematic majored research
💻 PY
字号:
"This module implements the tabulation of monomial forms, large parts are copied from monomialintegration.py"__author__ = "Kristian B. Oelgaard (k.b.oelgaard@tudelft.nl)"__date__ = "2007-03-23 -- 2007-06-19"__copyright__ = "Copyright (C) 2007 Kristian B. Oelgaard"__license__  = "GNU GPL version 3 or any later version"# Python modulesimport numpyimport time# FIAT modulesfrom FIAT.quadrature import *from FIAT.shapes import *# FFC common modulesfrom ffc.common.debug import *# FFC language modulesfrom ffc.compiler.language.index import *from ffc.compiler.language.integral import *from ffc.compiler.language.restriction import *# FFC tensor representation modulesfrom ffc.compiler.representation.tensor.multiindex import *from ffc.compiler.representation.tensor.pointreordering import *class Quadrature:    """This class contains quadrature information    Attributes:        points    - quadrture points        weights   - weights in quadrature_points    """    def __init__(self, points, weights):        "Create quadrture object"        self.points  = points        self.weights = weightsdef tabulate(monomial, facet0, facet1, num_quad_points):    """Tabulate the element tensor for a given monomial term of a    multilinear form"""    tic = time.time()    # Check for integral type    integral_type = monomial.integral.type    # Initialize quadrature points and weights    (points, weights) = __init_quadrature(monomial.basisfunctions, integral_type, num_quad_points)    num_quadrature_points = len(weights)    # Correction of weights by numeric constant if any. (This might be wrong!!!)    quadrature = Quadrature(points, weights*monomial.numeric)    # Initialize quadrature table for basis functions    table = __init_table(monomial.basisfunctions, integral_type, points, facet0, facet1)    # Compute table Psi for each factor    psis = [__compute_psi(v, table, len(points), integral_type) for v in monomial.basisfunctions]    toc = time.time() - tic    return (psis, quadrature)# Use for non-affine mapping?#    return (map_derivatives, map_element, psis, quadrature)#    return (Derivatives, num_quadrature_points, psis)def __init_quadrature(basisfunctions, integral_type, num_quad_points):    "Initialize quadrature for given monomial term."    # Get shape (check first one, all should be the same)    shape = basisfunctions[0].element.cell_shape()    facet_shape = basisfunctions[0].element.facet_shape()    # Compute number of points to match the degree    q = __compute_degree(basisfunctions)    m = (q + 1 + 1) / 2 # integer division gives 2m - 1 >= q    debug("Total degree is %d, using %d quadrature point(s) in each dimension" % (q, m), 1)    # Use user specified number of quadrature points if present    if num_quad_points:        m = num_quad_points    # Create quadrature rule and get points and weights    # FIXME: FIAT not finiteelement should return shape of facet    if integral_type == Integral.CELL:        quadrature = make_quadrature(shape, m)    elif integral_type == Integral.EXTERIOR_FACET:        quadrature = make_quadrature(facet_shape, m)    elif integral_type == Integral.INTERIOR_FACET:        quadrature = make_quadrature(facet_shape, m)    points = quadrature.get_points()    weights = quadrature.get_weights()    return (points, weights)def __init_table(basisfunctions, integral_type, points, facet0, facet1):    """Initialize table of basis functions and their derivatives at    the given quadrature points for each element."""    # Compute maximum number of derivatives for each element    num_derivatives = {}    for v in basisfunctions:        element = v.element        order = len(v.derivatives)        if element in num_derivatives:            num_derivatives[element] = max(order, num_derivatives[element])        else:            num_derivatives[element] = order    # Call FIAT to tabulate the basis functions for each element    table = {}    for element in num_derivatives:        order = num_derivatives[element]        # Tabulate for different integral types        if integral_type == Integral.CELL:            table[(element, None)] = element.tabulate(order, points)        elif integral_type == Integral.EXTERIOR_FACET:            table[(element, None)] = element.tabulate(order, points, facet0)        elif integral_type == Integral.INTERIOR_FACET:            table[(element, Restriction.PLUS)]  = element.tabulate(order, points, facet0)            table[(element, Restriction.MINUS)] = element.tabulate(order, points, facet1)    return tabledef __compute_psi(v, table, num_points, integral_type):    "Compute the table Psi for the given BasisFunction v."    # We just need to pick the values for Psi from the table, which is    # somewhat tricky since the table created by tabulate_jet() is a    # mix of list, dictionary and numpy.array.    #    # The dimensions of the resulting table are ordered as follows:    #    #     one dimension  corresponding to quadrature points    #     all dimensions corresponding to auxiliary Indices    #     all dimensions corresponding to primary   Indices    #     all dimensions corresponding to secondary Indices    #    # All fixed Indices are removed here.    # Get cell dimension    cell_dimension = v.element.cell_dimension()    # Get indices and shapes for components    if len(v.component) ==  0:        cindex = []        cshape = []    elif len(v.component) == 1:        cindex = [v.component[0]]        cshape = [len(v.component[0].range)]    else:        raise RuntimeError, "Can only handle rank 0 or rank 1 tensors."    # Get indices and shapes for derivatives    dindex = [d.index for d in v.derivatives]    dshape = [len(d.index.range) for d in v.derivatives]    dorder = len(dindex)    # Get indices and shapes for basis functions    vindex = [v.index]    vshape = [len(v.index.range)]    # Create list of indices that label the dimensions of the tensor Psi    indices = cindex + dindex + vindex    shapes = cshape + dshape + vshape + [num_points]    dimensions = cshape + dshape + vshape    # Initialize tensor Psi: component, derivatives, basis function, points    Psi = numpy.zeros(shapes, dtype = numpy.float)    # Get restriction and handle constants    restriction = v.restriction    if restriction == Restriction.CONSTANT:        if integral_type == Integral.INTERIOR_FACET:            restriction = Restriction.PLUS        else:            restriction = None    # Iterate over derivative indices    dlists = build_indices([index.range for index in dindex]) or [[]]    if len(cindex) > 0:        etable = table[(v.element, restriction)]        for component in range(len(cindex[0].range)):            for dlist in dlists:                # Translate derivative multiindex to lookup tuple                dtuple = __multiindex_to_tuple(dlist, cell_dimension)                # Get values from table                Psi[component][tuple(dlist)] = etable[cindex[0].range[component]][dorder][dtuple]    else:        etable = table[(v.element, restriction)][dorder]        for dlist in dlists:            # Translate derivative multiindex to lookup tuple            dtuple = __multiindex_to_tuple(dlist, cell_dimension)            # Get values from table            Psi[tuple(dlist)] = etable[dtuple]    # Rearrange Indices as (fixed, auxiliary, secondary, primary)    (rearrangement, num_indices) = __compute_rearrangement(indices)    indices = [indices[i] for i in rearrangement]    # Rearrange Psi    Psi = numpy.transpose(Psi, rearrangement + (len(indices),))    # Remove fixed indices from Psi and indices    for i in range(num_indices[0]):        Psi = Psi[0, ...]    indices = [index for index in indices if not index.type == Index.FIXED]    # Compute auxiliary index positions for current Psi (I don't use this? problems?)    bpart = [i.index for i in indices if i.type == Index.AUXILIARY_0]    # Return Psis the list of indices, and the index of the basis function    return (Psi, indices, vindex[0])def __compute_degree(basisfunctions):    "Compute total degree for given monomial term."    q = 0    for v in basisfunctions:        q += v.element.degree()        for d in v.derivatives:            q -= 1    return qdef __compute_rearrangement(indices):    """Compute rearrangement tuple for given list of Indices, so that    the tuple reorders the given list of Indices with fixed, auxiliary,    secondary and primary Indices in rising order."""    fixed     = __find_indices(indices, Index.FIXED)    auxiliary = __find_indices(indices, Index.AUXILIARY_0)    primary   = __find_indices(indices, Index.PRIMARY)    secondary = __find_indices(indices, Index.SECONDARY)    assert len(fixed + auxiliary + primary + secondary) == len(indices)    return (tuple(fixed + auxiliary + secondary + primary), \            (len(fixed), len(auxiliary), len(secondary), len(primary)))def __find_indices(indices, index_type):    "Return unsorted list of positions for given Index type."#    pos = [i for i in range(len(indices)) if indices[i].type == index_type]#    val = [indices[i].index for i in range(len(indices)) if indices[i].type == index_type]#    return [pos[i] for i in numpy.argsort(val)]    return [i for i in range(len(indices)) if indices[i].type == index_type]def __multiindex_to_tuple(dindex, cell_dimension):    """Compute lookup tuple from given derivative    multiindex. Necessary since the table we get from FIAT is a    dictionary with the tuples as keys. A derivative tuple specifies    the number of derivatives in each space dimension, rather than    listing the space dimensions for the derivatives."""    dtuple = [0 for i in range(cell_dimension)]    for d in dindex:        dtuple[d] += 1    return tuple(dtuple)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -