Advanced Finite Element

  • Upload
    rs0004

  • View
    249

  • Download
    0

Embed Size (px)

Citation preview

  • 8/8/2019 Advanced Finite Element

    1/172

  • 8/8/2019 Advanced Finite Element

    2/172

  • 8/8/2019 Advanced Finite Element

    3/172

    Workbook of Applications in VectorSpace C++ Library 453

    Mixed and Hybrid Finite Element Methods

    Eq. 512

    where and with over-bar are fixed nodal flux boundary conditions and fixed nodal temperature boundary

    conditions, respectively, while h in Eq. 512 can be specified as a function on an element boundary. The fixed

    nodal boundary conditions, and , in Eq. 511 and Eq. 512 are encountered frequently in finite element

    method and are taken care of by fe.lib as default behaviors behind the scene. This is consistent with the treat-

    ment of the result of the displacementboundary conditions as reaction, and substrates out of the nodal force term

    as -= K .

    By inspecting on Eq. 59 and Eq. 510, the derivatives of temperature field exist. C0-continuity of T on the

    element interior and boundaries is required. This is needed to guarantees that Eq. 510 over the entire problemdomain is integrable. Otherwise, the integration goes to infinity at the discontinuities. Two triangular elements

    are considered in the following computations. Figure 51a&b shows that two triangular elements with linear tem-

    perature field with three corner nodes and either a constant heat flux with one node at the center of the element or

    linear heat flux with three nodes at the Gaussian integration points. We notice that the temperature nodes on the

    three corners is necessary to ensure the C0-continuity on the element boundaries, while the heat flux, with no

    derivatives of heat flux in Eq. 59 and Eq. 510, can be discontinuous at the element boundaries. Therefore, the

    constant heat flux element has one node at the center of the element (Figure 51a), and the linear heat flux ele-

    ment has three nodes at the Gaussian integration points (Figure 51b). Actually, requiring heat flux to be C0-con-tinuity on the element boundaries, had we use three corner nodes for the heat flux, may cause physically

    incorrect conditions.1

    Recall in Section 4.2.5, the mixed formulation for one dimensional beam bending problem, we have extended

    fe.lib with the object-oriented modeling for developing matrix substructuring to solve system of equations in

    submatrices similar to Eq. 58.

    1. e.g. as discussed in p.327 in Zienkiewicz, O.C. and R.L. Taylor, 1991, The finite element method, 4th ed., vol. 1.McGraw-Hill, Inc., UK.

    f2 T f de

    T h dh

    e

    Ch he+=

    h g

    h g

    f u

    Figure 51 Triangluar elements with linear temperature with three corner nodes, and eitherconstant heat flux with one node at the center or linear heat flux with three nodes at three Gaussintegration points.

    T-nodesq-nodes

    (a) Constantheat flux

    (b) Linearheat flux

    T = 0oC

    T = 30oC

    q = 0q = 0

    (c)

    http://finiteelement.fm.pdf/http://finiteelement.fm.pdf/
  • 8/8/2019 Advanced Finite Element

    4/172

    Advanced Finite Element Methods

    454 Workbook of Applications in VectorSpace C++ Library

    Chapter 5

    The Program Listing 51 implements the constant heat flux triangular element for the mixed formulation. For

    global discretization {h, qh}, with its element discretization as qe, the heat flux is constant over entire domain

    ofqe. Only one node at the center of the element is needed. However we still need to specify the three corner

    nodes in order to (1) compute the coordinates of the center node, (2) define coordinate transformation rule, and(3) perform integration. Therefore, the three additional corner nodes of q

    e are defined as geometrical nodes.

    The geometrical nodes has no variable associated with them. A simple trick using fe.lib is to disable all geo-

    metrical nodes by specifying all these nodes to have Dirichlet type boundary condition, so they will be left out of

    the global stiffness matrix. The A-submatrix are defined by

    1 double k_x = 1.0, k_y = 1.0,

    2 k_inv[2][2] = { {1.0/k_x, 0.0 }, // , for isotropy

    3 {0.0, 1.0/k_y }};4 C0 K_inv = MATRIX("int, int, const double*", 2, 2, k_inv[0]);

    5 Heat_Mixed_Formulation::Heat_Mixed_Formulation(int en, Global_Discretization& gd) :

    6 Element_Formulation_Couple(en, gd) {

    7 Quadrature qp(2, 4);

    8 H1 L(2, (double*)0, qp),

    9 n = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", 3, 2, qp),

    10 L0 = L[0], L1 = L[1], L2 = 1.0 - L0 - L1; // area coordinates for a triangle

    11 n[0] = L0; n[1] = L1; n[2] = L2;12 C0 x = MATRIX("int, int, C0&, int, int", 3, 2, xl, 0, 0);

    13 H1 X = n*x;

    14 J dv(d(X).det()/2.0);

    15 H0 N = INTEGRABLE_VECTOR("int, Quadrature", 4, qp);

    16 N[0] = N[1] = N[2] = 0.0; N[3] = 1.0;

    17 H0 N_q = ((~N) || C0(0.0)) &

    18 (C0(0.0) || (~N) ); //

    19 stiff &= ((~N_q) * (K_inv * N_q)) | dv;20 }

    The area coordinates for triangle,L0,L1, andL2, are used for coordinate transformation and integration. The first

    three nodes are geometrical nodes at three corners and the fourth-node is the q-node at the center. A reference

    matrix x (line 12) is constructed to refer to the first three coordinates of xl, which leaves out the q-node. To

    compute the Jacobian we notice that there is a factor of 1/2 for a triangular element comparing to the a quadrilat-

    eral element where the factor = 1 (note that a factor of 1/6 is to be used for a 3-D tetrahedra element). The q-

    shape function, N (line 16), is defined that the first three shape functions corresponding to three geometrical

    nodes are zero; i.e., N[0] = N[1] = N[2] = 0. And the fourth shape function is one; i.e., N[3] = 1. The ele-

    ment stiffness matrix so constructed will have the size of 8 8, with only the 2 2 submatrix at the lower-right

    corner, corresponding to the center q-node, contains no zero components. All the geometrical nodes are to be

    specified with Dirichlet type boundary condition. Dummy variables corresponding to these geometrical nodes

    will all be eliminated from the global matrix and the global vector. Therefore, the no trivial 2 2 element subma-

    trix will enter the global stiffness matrix.

    The C-submatrix can be defined as

    1 1 ij 1 0

    0 1

    = =

    A q 1 q( ) de

    =

  • 8/8/2019 Advanced Finite Element

    5/172

  • 8/8/2019 Advanced Finite Element

    6/172

    Advanced Finite Element Methods

    456 Workbook of Applications in VectorSpace C++ Library

    Chapter 5

    hdisable all geometrical nodes on q

    gtop boundary: T = 30o

    bottom boundary: T = 0o

    for diagonal submatrix A

    for off-diagonal submatrix C

    A-submatrix element formulation

    area coordinates for triangle

    linear triangular shape function for

    coordinate transformation

    = 1.0 (constant over element)

    N[0], N[1], N[2] are geometrical nodes

    N[3] is constant over element domain

    q

    ena[0] = first_corner_node_no; ena[1] = first_corner_node_no+1+row_t_node_no;

    ena[2] = first_corner_node_no+row_t_node_no;

    elem = new Omega_eh(element_no+1, 0, 0, 3, ena); omega_eh_array().add(elem);

    }

    }}

    gh_on_Gamma_h_i::gh_on_Gamma_h_i(int i, int df, Omega_h& omega_h) : gh_on_Gamma_h() {

    gh_on_Gamma_h::__initialization(df, omega_h);

    if(i == 0) {

    for(int j = (row_t_node_no-1)*6*(row_t_node_no-1);

    j < (row_t_node_no*row_t_node_no+(row_t_node_no-1)*6*(row_t_node_no-1)); j++)

    for(int k = 0; k < 2; k++) {

    the_gh_array[node_order(j)](k) = gh_on_Gamma_h::Dirichlet;

    the_gh_array[node_order(j)][k] = 0.0;

    }

    } else if(i == 1) {

    for(int j = 0; j < row_t_node_no; j++) {

    the_gh_array[node_order(row_t_node_no*(row_t_node_no-1)+j)](0) =

    gh_on_Gamma_h::Dirichlet;

    the_gh_array[node_order(row_t_node_no*(row_t_node_no-1)+j)][0] =

    ((double)(row_t_node_no-1))*10.0;

    the_gh_array[node_order(j)](0) = gh_on_Gamma_h::Dirichlet;

    the_gh_array[node_order(j)][0] = 0.0;

    }

    }

    }static const int q_ndf = 2; static Omega_h_i oh_q(0);

    static gh_on_Gamma_h_i q_gh(0, q_ndf, oh_q); static U_h q_h(q_ndf, oh_q);

    static Global_Discretization q_gd(oh_q, q_gh, q_h);

    static const int T_ndf = 1; static Omega_h_i oh_T(1);

    static gh_on_Gamma_h_i T_gh(1, T_ndf, oh_T); static U_h T_h(T_ndf, oh_T);

    static Global_Discretization T_gd(oh_T, T_gh, T_h);

    static Global_Discretization_Couple gdc(T_gd, q_gd);

    class Heat_Mixed_Formulation : public Element_Formulation_Couple {

    public:

    Heat_Mixed_Formulation(Element_Type_Register a) : Element_Formulation_Couple(a) {}Element_Formulation *make(int, Global_Discretization&);

    Heat_Mixed_Formulation(int, Global_Discretization&);

    Element_Formulation_Couple *make(int, Global_Discretization_Couple&);

    Heat_Mixed_Formulation(int, Global_Discretization_Couple&);

    };

    Element_Formulation* Heat_Mixed_Formulation::make(int en, Global_Discretization& gd) {

    return new Heat_Mixed_Formulation(en,gd);

    }

    Heat_Mixed_Formulation::Heat_Mixed_Formulation(int en, Global_Discretization& gd) :

    Element_Formulation_Couple(en, gd) {Quadrature qp(2, 4);

    H1 L(2, (double*)0, qp),

    n = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", 3, 2, qp),

    L0 = L[0], L1 = L[1], L2 = 1.0 - L0 - L1;

    n[0] = L0; n[1] = L1; n[2] = L2;

    C0 x = MATRIX("int, int, C0&, int, int", 3, 2, xl, 0, 0);

    H1 X = n*x;

    J dv(d(X).det()/2.0);

    H0 N = INTEGRABLE_VECTOR("int, Quadrature", 4, qp);

    N[0] = N[1] = N[2] = 0.0;

    N[3] = 1.0;

  • 8/8/2019 Advanced Finite Element

    7/172

  • 8/8/2019 Advanced Finite Element

    8/172

    Advanced Finite Element Methods

    458 Workbook of Applications in VectorSpace C++ Library

    Chapter 5

    1 Heat_Mixed_Formulation::Heat_Mixed_Formulation(int en, Global_Discretization_Couple& gdc)

    2 : Element_Formulation_Couple(en, gdc) {

    3 Quadrature qp(2, 4);

    4 H1 L(2, (double*)0, qp),5 n = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE(

    6 "int, int, Quadrature", 3/*nen*/, 2/*nsd*/, qp),

    7 L0 = L[0], L1 = L[1], L2 = 1.0 - L0 - L1;

    8 n[0] = L0; n[1] = L1; n[2] = L2;

    9 H1 X = n*xl;

    10 H0 nx = d(n) * d(X).inverse();

    11 J dv(d(X).det()/2.0);

    12 H0 N = INTEGRABLE_VECTOR("int, Quadrature", 4/*nen*/, qp);13 N[0] = N[1] = N[2] = 0.0; N[3] = 1.0;

    14 H0 N_q = ( (~N) || C0(0.0)) &

    15 (C0(0.0) || (~N)); //

    16 stiff &= (nx * N_q) | dv;

    17 }

    The element stiffness matrix so generated has the size of 3 8. The three rows (number of equations) corre-

    sponding to three temperature nodes at the corner. After the element to global mapping, the first 6 columns (cor-responding to the number of dummy variables) for the geometrical nodes will not enter the global stiffness

    matrix. Only the last 2 columns (corresponding to the number of variables) for the center q-node will survive.

    After the submatrices have been formed, the solution of system of equation in Eq. 58 is the subject ofcon-

    straint optimization problem (see Section 2.3.3 in Chapter 2). In the context of finite element problem, the objec-

    tive functional for optimization is quadratic. The problem is further restricted to a quadratic programming

    problem, in which only one step along the search path is needed to reach the exact solution (see introduction and

    its example in page 145). We discuss the range space methodand null space method(see page 149) to solve Eq.58 in the followings.

    From first equation ofEq. 58 we have

    A + CT = f1 Eq. 513

    Considering A is symmetrical positive definitive, therefore it can be inverted, we can solve for q by

    = A-1 f1 - A-1CT Eq. 514

    Substituting Eq. 514 into second equation ofEq. 58,C = f2, we have

    CA-1 f1 - C A-1CT = f2 Eq. 515

    Therefore, can also be solved considering that the similarity transformation ofA-1 as C A-1CT preserves

    the symmetrical positive definitiveness ofA-1. An alternative view is that C A-1CT is the projection of inverse

    C T q de

    =

    q T

    q T

    q

    T

    T

    http://optimization.fm.pdf/http://optimization.fm.pdf/http://optimization.fm.pdf/http://optimization.fm.pdf/http://optimization.fm.pdf/http://optimization.fm.pdf/
  • 8/8/2019 Advanced Finite Element

    9/172

  • 8/8/2019 Advanced Finite Element

    10/172

    Advanced Finite Element Methods

    460 Workbook of Applications in VectorSpace C++ Library

    Chapter 5

    17 for(int i = 0; i < q_h.total_node_no(); i++)

    18 cout

  • 8/8/2019 Advanced Finite Element

    11/172

    Workbook of Applications in VectorSpace C++ Library 461

    Mixed and Hybrid Finite Element Methods

    Both the range space and null space method reproduce the exact solution up to round-off error for the current

    problem. The nodal temperature solutions at the second row is = 10 oC, and the third row is = 20 oC. All

    heat flux center nodes have the values of = [0, -10]T per unit length. The default method in Program Listing

    51 is the range space method. The null space method can be activated by setting macro definition__NULL_SPACE_METHOD at compile time.

    The linear heat flux with three nodes at the Gaussian integration points (see Figure 51b) can be activated by

    setting macro definition __TEST_THREE_NODES_DISCONTINUOUS_HEAT_FLUX at compile time. The

    triangular element in this implementation used shape functions degenerated from bilinear 4-node element. The

    results of this linear heat flux element is identical to that of the constant heat flux element. Considering that T-

    field only for a 3-node triangular element vary linearly. The heat flux, computed from the Fouries law, is the

    derivative of the linear T-field, which is constant. Therefore, the linear heat flux element does not give any

    improvement in the accuracy of the solution comparing to the constant heat flux element. Actually, the linear

    heat flux element produces the same result as the constant heat flux element. This is known as the limitationprin-

    ciple by Fraeijs de Veubeke.

    With the assistance of object-oriented modeling provided in fe.lib for handling the matrix substructuring, it

    may seems to be a piece of cake to implement the multiple-field mixed formulation. It is not so for most existing

    finite element programs. It has been remarked that the full-scale multiple-field formulations are rarely imple-

    mented for practical computation.1

    The discontinuous heat flux field, with nodes reside only inside an element, not only avoid physically incor-

    rect conditions as mentioned earlier, but it also has the advantage that the heat flux field can be eliminated at the

    element level. Every heat flux node belongs only to its containing element; i.e., there are no shared heat flux

    nodes with the neighboring elements. Therefore, from Eq. 516 that

    = (C A-1CT)-1 (CA-1 f1 - f2)

    We can redefine element stiffness matrix and element force vector as

    ke = Ce Ae-1CeT, and fe= CeAe-1 f1e - f2

    e Eq. 519

    respectively, with

    Eq. 520

    and,

    Eq. 521

    1. see p.206 in Hughes, T. J.R., The finite element method: linear static and dynamic finite element analysis, Prentice-Hall,Inc., Englewood Cliffs, New Jersey.

    T T

    q

    T

    f2e T f d

    e=

    T h dhe Ceh he 0=

  • 8/8/2019 Advanced Finite Element

    12/172

    Advanced Finite Element Methods

    462 Workbook of Applications in VectorSpace C++ Library

    Chapter 5

    Since in this discontinuous heat flux element no heat flux boundary condition can be specified, the temperature

    boundary conditions in Eq. 58 are simply

    f1 = - Eq. 522

    Substituting the element level vector ofEq. 522 into the second equation in Eq. 519, we have

    fe = - CeAe-1 - f2e= - Ce Ae-1 - f2

    e

    = -ke - f2e Eq. 523

    The first term in the right-hand-side is consistent with standard implementation of finite element on the essential

    boundary conditions. The mixed form ofEq. 519 can be easily implemented which does not require the mecha-

    nism provided in the fe.lib to express matrix substructuring. Program Listing 52 implements Eq. 519 (project

    mixed_T_heat_conduction in project workspace file fe.dsw). The temperature solutions of the computation

    is certainly identical to the full-fledged mixed formulation. The program is significant simplified comparing to

    the full-scale mixed formulation.

    CT

    g g

    CeT

    gege

    CeT

    gege

    ge ge

  • 8/8/2019 Advanced Finite Element

    13/172

    Workbook of Applications in VectorSpace C++ Library 463

    Mixed and Hybrid Finite Element Methods

    #include "include\fe.h"

    static row_node_no = 4;

    EP::element_pattern EP::ep = EP::SLASH_TRIANGLES;

    Omega_h::Omega_h() {double coord[4][2] = {{0.0, 0.0}, {3.0, 0.0}, {3.0, 3.0}, {0.0, 3.0}};

    int control_node_flag[4] = {TRUE, TRUE, TRUE, TRUE};

    block(this, row_node_no, row_node_no, 4, control_node_flag, coord[0]);

    }

    gh_on_Gamma_h::gh_on_Gamma_h(int df, Omega_h& omega_h) { __initialization(df, omega_h);

    for(int j = 0; j < row_node_no; j++) {

    the_gh_array[node_order(row_node_no*(row_node_no-1)+j)](0) =

    the_gh_array[node_order(j)](0) = gh_on_Gamma_h::Dirichlet;

    the_gh_array[node_order(row_node_no*(row_node_no-1)+j)][0] =

    ((double)(row_node_no-1))*10.0;

    the_gh_array[node_order(j)][0] = 0.0;

    }

    }

    class HeatMixedT3 : public Element_Formulation {

    public:

    HeatMixedT3(Element_Type_Register a) : Element_Formulation(a) {}

    Element_Formulation *make(int, Global_Discretization&);

    HeatMixedT3(int, Global_Discretization&);

    };

    Element_Formulation* HeatMixedT3::make(int en, Global_Discretization& gd) {

    return new HeatMixedT3(en,gd); }double k_x = 1.0, k_y = 1.0, k_inv[2][2] = { {1.0/k_x, 0.0}, { 0.0, 1.0/k_y}};

    C0 K_inv = MATRIX("int, int, const double*", 2, 2, k_inv[0]);

    HeatMixedT3::HeatMixedT3(int en, Global_Discretization& gd) : Element_Formulation(en, gd) {

    Quadrature qp(2, 4);

    H1 L(2, (double*)0, qp),

    n = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", 3, 2, qp),

    L0 = L[0], L1 = L[1], L2 = 1.0 - L0 - L1;

    n[0] = L0; n[1] = L1; n[2] = L2;

    H1 X = n*xl; H0 nx = d(n) * d(X).inverse(); J dv(d(X).det()/2.0);

    H0 N = INTEGRABLE_SCALAR("Quadrature", qp); N = 1.0;

    H0 N_q = ((~N) || C0(0.0)) &(C0(0.0)|| (~N));

    C0 C = (nx * N_q) | dv,

    A = ((~N_q) * (K_inv * N_q)) | dv,

    A_inv = A.inverse();

    stiff &= C*A_inv*(~C);

    }

    Element_Formulation* Element_Formulation::type_list = 0;

    Element_Type_Register element_type_register_instance;

    static HeatMixedT3 heatmixedt3_instance(element_type_register_instance);

    int main() {int ndf = 1; Omega_h oh; gh_on_Gamma_h gh(ndf, oh); U_h uh(ndf, oh);

    Global_Discretization gd(oh, gh, uh);

    Matrix_Representation mr(gd);

    mr.assembly();

    C0 u = ((C0)(mr.rhs())) / ((C0)(mr.lhs()));

    uh = u; uh = gh;

    cout

  • 8/8/2019 Advanced Finite Element

    14/172

    Advanced Finite Element Methods

    464 Workbook of Applications in VectorSpace C++ Library

    Chapter 5

    Hourglass Element

    For the irreducible formulation in Chapter 4, 2 2 Gaussian integration points are used to compute element

    stiffness matrix for bilinear 4-node element.

    Eq. 524

    where

    Eq. 525

    and a = 0, 1, 2, 3. A reduced integration (1 Gauss point at the center of the element) will result in rank deficiency

    of the element stiffness matrix. The rank of the element stiffness matrix is the number of integration points times

    the number of independent relations. In the case of heat conduction, the number of independent relations is the

    number of equations relating the heat flux [qx, qy] and the temperature gradients [T/x, T/y] by Fourier lawof heat conduction in 2-D. Therefore, the rank of the stiffness matrix for 1-point Gauss integration rule is 2 (=2 1). For the element stiffness matrix of size 4 4 in Eq. 524, the 1-point Gauss integration leads to rank defi-

    ciency of 2 (= 4-2). We can consider that the 1-point integration stiffness matrix is span bybx = {bxa,bya} in Eq.

    525, which are bases in 4. The two spurious zero energy modes in the null space are constant solution mode

    with nodal solution ofsa = [1, 1, 1, 1] and hourglass mode with nodal solution of ha = [-1, 1, -1, 1]. The hour-

    glass mode is illustrated in Figure 52. The two zero energy modes are orthogonal tobx

    , and Eq. 526

    where we also denote x0 = x, and x1 = y. We notice that for isoparametric coordinate transformation xi =Naxia ,

    we have the relation

    ke N( )TN( )d

    e

    BTB( )de

    = =

    Ba bxa

    bya

    Na

    x----------

    Nay

    ----------

    -1

    -0.5

    0

    0.5

    1

    -1

    -0.5

    0

    0.5

    1

    -1

    -0.5

    0

    0.5

    1

    -1

    -0.5

    0

    0.5

    -1

    -0.5

    0

    0.5

    -1

    -0.5

    0

    .5

    1

    Figure 52 The hourglass mode for heat conduction problem.

    T

    bxis 0= bxi

    h 0=

  • 8/8/2019 Advanced Finite Element

    15/172

    Workbook of Applications in VectorSpace C++ Library 465

    Mixed and Hybrid Finite Element Methods

    Eq. 527

    The constant nodal solution sa is considered proper, since a constant temperature field produces no heat flux isas expected, while the hourglass mode ha has gradient far from zero (see Figure 52) but no heat flux production,

    which is considered improper. Therefore, we expect the 4-node element stiffness to produce a rank 3 matrix.

    The strategy is to use a so-called trial hourglass mode, a , to construct a correct-ranked stiffness ke in a way thatis very economical to compute as

    ke = ke(1-point) + ke(hourglass) Eq. 528

    The first term on the right hand side, ke(1-point) is standard stiffness matrix computed with only one Gaussianintegration point. The second term ke(hourglass) is to be constructed with the trial hourglass mode a. The generalform of the trial hourglass mode, a , in

    4 is span by the four bases [bxa,bya, sa, ha] as

    a = a0bxa + a1bya + a2sa+ ha Eq. 529

    a is required to be orthogonal with an arbitrary lineartemperature field of Ta

    Ta = c0 xa + c1ya + c2sa Eq. 530

    For a to be always orthogonal with arbitrary coefficients, ci , in Eq. 530, we have

    a xa = 0 , a ya = 0, and asa = 0 Eq. 531

    From last part ofEq. 531, no component ofa is in sa, so in Eq. 529 a2 = 0, and we have this equation re-writ-ten as

    a = a0bxa + a1bya + ha Eq. 532

    Substituting Eq. 532 into a xa = 0 in the first part ofEq. 531, and usingbxa xa = 1, andbya xa = 0 as indicatedin Eq. 527, we have

    a0 = - ha xa Eq. 533

    Similarly, substituting Eq. 532 into a ya = 0 in the second part ofEq. 531, and usingbya ya = 1, andbxa ya = 0

    as in Eq. 527, we have

    a1 = - ha ya Eq. 534

    Therefore, we show that

    a = ha - (ha xa)bxa - (ha ya)bya Eq. 535

    The hourglass stiffness can be defined as1

    bxixj

    Nxi-------x

    j

    ij= =

  • 8/8/2019 Advanced Finite Element

    16/172

    Advanced Finite Element Methods

    466 Workbook of Applications in VectorSpace C++ Library

    Chapter 5

    Eq. 536

    where

    ais

    anormalized to

    ||a||= 2, b = [b

    x,b

    y]T, and . Program Listing 53 implements the

    hourglass element for heat conduction (project hourglass_heat in project workspace filefe.dsw).

    We measure the time spent in the computation of stiffness matrix for the heat conduction element with irre-

    ducible formulation in Chapter 4. It takes 3.5 seconds to assemble the stiffness on an obsolete 166 MHz PC. For

    the mixed formulation in the last section, although we gain significant freedom in terms of formulation, the

    assemble of diagonal and off-diagonal stiffness matrices (A and C) takes 6.2 seconds on the same computer. The

    hourglass element takes only 0.5 second to assemble the stiffness.

    1. see similar derivation for elasticity in p.251-254 in Hughes, T. J.R., The finite element method: linear static and dynamicfinite element analysis, Prentice-Hall, Inc., Englewood Cliffs, New Jersey, and references therein.

    ke hourg la ss( )kJ b b( )

    12----------------------- ( )

    J det x

    ( )

  • 8/8/2019 Advanced Finite Element

    17/172

    Workbook of Applications in VectorSpace C++ Library 467

    Mixed and Hybrid Finite Element Methods

    #include "include\fe.h"

    EP::element_pattern EP::ep = EP::QUADRILATERALS_4_NODES;

    Omega_h::Omega_h() {

    double coord[4][2] = {{0.0, 0.0}, {3.0, 0.0}, {3.0, 3.0}, {0.0, 3.0}};int control_node_flag[4] = {1, 1, 1, 1};

    block(this, 4, 4, 4, control_node_flag, coord[0]);

    }

    gh_on_Gamma_h::gh_on_Gamma_h(int df, Omega_h& omega_h) {

    __initialization(df, omega_h);

    int row_node_no = 4;

    for(int i = 0; i < row_node_no; i++) {

    the_gh_array[node_order(i)](0) = gh_on_Gamma_h::Dirichlet;

    the_gh_array[node_order(row_node_no*(row_node_no-1)+i)](0) =

    gh_on_Gamma_h::Dirichlet;

    the_gh_array[node_order(row_node_no*(row_node_no-1)+i)][0] = 30.0;}

    }

    class HourGlassHeatQ4 : public Element_Formulation { public:

    HourGlassHeatQ4(Element_Type_Register a) : Element_Formulation(a) {}

    Element_Formulation *make(int, Global_Discretization&);

    HourGlassHeatQ4(int, Global_Discretization&);

    };

    Element_Formulation* HourGlassHeatQ4::make(int en, Global_Discretization& gd) {

    return new HourGlassHeatQ4(en,gd);

    }

    HourGlassHeatQ4::HourGlassHeatQ4(int en, Global_Discretization& gd) :

    Element_Formulation(en, gd) {

    Quadrature qp(2, 1);

    H1 Z(2, (double*)0, qp), Zai, Eta,

    N = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", 4, 2, qp);

    Zai &= Z[0]; Eta &= Z[1];

    N[0] = (1-Zai)*(1-Eta)/4; N[1] = (1+Zai)*(1-Eta)/4;

    N[2] = (1+Zai)*(1+Eta)/4; N[3] = (1-Zai)*(1+Eta)/4;

    H1 X = N*xl; H0 Nx = d(N) * d(X).inverse(); J dv(d(X).det());

    double k_ = 1.0; C0 K_standard = (Nx * k_ * (~Nx)) | dv;

    C0 h(4, (double*)0); h[3] = 1.0;C0 phi = h - Nx.quadrature_point_value(0)*((~xl)*h);

    double factor = 2.0/norm(phi); phi *= factor;

    H0 b = Nx(0) & Nx(1);

    double j = (double)(d(X).det().quadrature_point_value(0));

    C0 K_hourglass = (k_*j*((~b)*b) | dv) /12.0 * (phi%phi);

    stiff &= K_standard + K_hourglass;

    }

    Element_Formulation* Element_Formulation::type_list = 0;

    Element_Type_Register element_type_register_instance;

    static HourGlassHeatQ4 hourglassheatq4_instance(element_type_register_instance);

    int main() {

    int ndf = 1; Omega_h oh; gh_on_Gamma_h gh(ndf, oh); U_h uh(ndf, oh);

    Global_Discretization gd(oh, gh, uh); Matrix_Representation mr(gd);

    mr.assembly();

    C0 u = ((C0)(mr.rhs())) / ((C0)(mr.lhs()));

    uh = u; uh = gh;

    cout

  • 8/8/2019 Advanced Finite Element

    18/172

    Advanced Finite Element Methods

    468 Workbook of Applications in VectorSpace C++ Library

    Chapter 5

    5.1.2 Mixed Formulation for Plane Elasticity

    In the irreducible formulation for plane elasticity, the displacement field, u, is the only variable that the vari-

    ation of the Lagrangian functional ( ), derived from the equilibrium equations, is taken as

    Eq. 537

    where the body force is denoted as b, the strain is defined as , and the differential operator L in matrix

    form as

    Eq. 538

    The traction boundary condition is t = h on h. In the mixed formulation, in addition to the variational approxi-

    mation on the equilibrium equations. we will also use the variational approximation to both the constitutiveequations and strain-displacement relations, separately. The interpolation functions (x) in finite elementapproximation of displacement field is taken as

    Eq. 539

    where is interpolation functions, and is nodal displacements. The subscript e denotes the element

    level.

    Hellinger-Reissner Variational Principle

    In addition to the variational principle based on equilibrium equation in Eq. 537, we consider the constitu-

    tive equation

    Eq. 540

    We also add stress field, , as additional variable in the Lagrangian functional such that

    Eq. 541

    Eq. 537 and Eq. 541 are the Euler-Lagrange equations corresponding to the Lagrangian functional.

    Eq. 542

    u( )

    u( ) Lu( )T d

    uT b d

    uTh d

    h

    =

    Lu=

    L

    x------ 0

    0

    y------

    y------

    x------

    ue ea x( )uea

    ea x( ) uea

    D DLu= =

    T Lu D 1 ( ) d 0=

    u,( )1

    2--- T

    D

    1

    d uT

    LT

    b+( ) d uT

    n h( ) dh+=

  • 8/8/2019 Advanced Finite Element

    19/172

    Workbook of Applications in VectorSpace C++ Library 469

    Mixed and Hybrid Finite Element Methods

    where t = n (the Cauchys formula). The Euler-Lagrange equations are obtained by taking the directional deriv-atives of the Lagrangian functional with respect to and u, then, make them equal to zero. Eq. 542 is known astheHellinger-Reissner variational principle. The finite element approximation of the stress field has interpola-

    tion function

    (x) in

    Eq. 543

    By inspecting Eq. 537 and Eq. 541, stress field has no derivatives taken on it. Therefore, the C0-continuity

    requirement on the element boundaries, to ensure the integral equation does not give infinity, can be dropped.

    The interpolation functions , in contrast to in Eq. 539, can be taken as piece-wise continuous func-

    tions across the entire problem domain. For example, for four stress nodes taken at Gauss integration points with

    the natural coordinates

    Eq. 544

    where a = 0, 1, 2, 3. The shape functions for these four nodes are

    Eq. 545

    If such discontinuous (at the element boundaries) interpolation is taken, the stress field can be approximated glo-

    bally. Because there is no inter-element dependency. The subscript e on can be dropped. The matrix form ofEq. 537 and Eq. 541, at element level, is

    Eq. 546

    where

    Eq. 547

    Eq. 548

    Eq. 549

    Eq. 550

    e ea x( )ea

    ea x( ) ea x( )

    a a,[ ]1

    3-------

    1

    3-------,

    1

    3-------

    1

    3-------,

    1

    3-------

    1

    3-------,

    1

    3-------

    1

    3-------,, , ,

    =

    ea x( )1

    4--- 1 3a+( ) 1 3a+( )

    A CT

    C 0

    u

    f1

    f2

    =

    A D 1 ( ) de

    =

    C B de=

    f1 A n( ) e CT

    u eu=

    f2 b d

    e

    n( ) de

    C n( ) e+=

    Ad d Fi i El M h dCh t 5

  • 8/8/2019 Advanced Finite Element

    20/172

    Advanced Finite Element Methods

    470 Workbook of Applications in VectorSpace C++ Library

    Chapter 5

    where B = L. Again, if discontinuous interpolation on were taken, all terms involving dropped out in Eq.511 and Eq. 512, which are then significantly simplified. To avoid singular conditions as discussed in Eq. 518

    we should have the condition to avoid singularity that

    Eq. 551

    Two quadrilateral elements with four -nodes and eight u-nodes (Q 4/8)1 are used to compute the beam bendingproblem in the higher-order path test in the Chapter 4. The numbers of degree of freedom for the two fields are

    n = 8 3 = 24, nu = 13 2-4 = 22, which satisfied the conceptual patch test criterion in Eq. 551. The implemen-tation ofEq. 58 to Eq. 512 is shown in Program Listing 54 (project hellinger_reissner_variational_principle

    in project workspace file fe.dsw). They present no new difficulty from the Program Listing 51. The solution

    of the tip-deflection is 0.75, which is exact.

    1. p.331 in Zienkiewicz, O.C. and R.L. Taylor, 1989, The finite element method, 4th ed., vol. 1. McGraw-Hill, Inc., UK.

    n nu

    Mi d d H b id Fi it El t M th d

  • 8/8/2019 Advanced Finite Element

    21/172

    Workbook of Applications in VectorSpace C++ Library 471

    Mixed and Hybrid Finite Element Methods

    1st element

    coordinates of four corner nodes

    physcial coordinates at ( )

    physcial coordinates at ( )

    physcial coordinates at ( )

    physcial coordinates at ( )

    2nd element

    node # 8-20 are geometrical nodes

    (serendipity)

    1

    3

    -------1

    3

    -------,

    1

    3-------

    1

    3-------,

    1

    3-------

    1

    3-------,

    1

    3------- 1

    3-------,

    #include "include\fe.h"

    #include "include\omega_h_n.h"

    Matrix_Representation_Couple::assembly_switch

    Matrix_Representation_Couple::Assembly_Switch = Matrix_Representation_Couple::ALL;

    static const int row_node_no = 5; static const int row_segment_no = row_node_no-1;

    static const double L_ = 10.0; static const double c_ = 1.0;

    static const double h_e_ = L_/((double)row_segment_no);

    static const double E_ = 1.e3; static const double v_ = 0.3;

    Omega_h_i::Omega_h_i( int i) : Omega_h(0) {

    if(i == 0) {

    double inv_sqrt3 = 1.0/sqrt(3.0), v[2], xl[4][2], zai, eta; Node *node;

    xl[0][0] = 0.0; xl[0][1] = 0.0; xl[1][0] = 2.0*h_e_; xl[1][1] = 0.0;

    xl[2][0] = 2.0*h_e_; xl[2][1] = 2.0*c_; xl[3][0] = 0.0; xl[3][1] = 2.0*c_;

    zai = - inv_sqrt3; eta = - inv_sqrt3;

    for(int j = 0; j < 2; j++) v[j] =(1.0-zai)*(1.0-eta)/4.0*xl[0][j]+(1.0+zai)*(1.0-eta)/4.0*xl[1][j]+(1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(0, 2, v); node_array().add(node);

    zai = inv_sqrt3; eta = - inv_sqrt3;

    for(int j = 0; j < 2; j++) v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(1, 2, v); node_array().add(node);

    zai = inv_sqrt3; eta = inv_sqrt3;

    for(int j = 0; j < 2; j++) v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(2, 2, v); node_array().add(node);

    zai = - inv_sqrt3; eta = inv_sqrt3;

    for(int j = 0; j < 2; j++) v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ 1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(3, 2, v); node_array().add(node);

    xl[0][0] = 2.0*h_e_; xl[0][1] = 0.0; xl[1][0] = 4.0*h_e_; xl[1][1] = 0.0;

    xl[2][0] = 4.0*h_e_; xl[2][1] = 2.0*c_; xl[3][0] = 2.0*h_e_; xl[3][1] = 2.0*c_;

    zai = - inv_sqrt3; eta = - inv_sqrt3;

    for(int j = 0; j < 2; j++) v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(4, 2, v); node_array().add(node);

    zai = inv_sqrt3; eta = - inv_sqrt3;for(int j = 0; j < 2; j++) v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(5, 2, v); node_array().add(node);

    zai = inv_sqrt3; eta = inv_sqrt3;

    for(int j = 0; j < 2; j++) v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(6, 2, v); node_array().add(node);

    zai = - inv_sqrt3; eta = inv_sqrt3;

    for(int j = 0; j < 2; j++) v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(7, 2, v); node_array().add(node);

    v[0] = 0.0; v[1] = 0.0; node = new Node(8, 2, v); node_array().add(node);

    v[0] = 1.0*h_e_; node = new Node(9, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(10, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(11, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(12, 2, v); node_array().add(node);

    v[0] = 0.0; v[1] = 1.0*c_; node = new Node(13, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(14, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(15, 2, v); node_array().add(node);

    v[0] = 0.0; v[1] = 2.0*c_; node = new Node(16, 2, v); node_array().add(node);

    v[0] = 1.0*h_e_; node = new Node(17, 2, v); node_array().add(node);

    Advanced Finite Element MethodsChapter 5

  • 8/8/2019 Advanced Finite Element

    22/172

    Advanced Finite Element Methods

    472 Workbook of Applications in VectorSpace C++ Library

    Chapter 5

    last four nodes are -nodes

    B.C.disable all geometrical nodesu B.C.

    fixed B.C. at right-end

    Bending Moment on left-end

    v[0] = 2.0*h_e_; node = new Node(18, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(19, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(20, 2, v); node_array().add(node);

    int ena[12]; Omega_eh *elem;

    ena[0] = 8; ena[1] = 10; ena[2] = 18; ena[3] = 16; ena[4] = 9; ena[5] = 14;

    ena[6] = 17; ena[7] = 13; ena[8] = 0; ena[9] = 1; ena[10] = 2; ena[11] = 3;

    elem = new Omega_eh(0, 0, 0, 12, ena); omega_eh_array().add(elem);

    ena[0] = 10; ena[1] = 12; ena[2] = 20; ena[3] = 18; ena[4] = 11; ena[5] = 15;

    ena[6] = 19; ena[7] = 14; ena[8] = 4; ena[9] = 5; ena[10] = 6; ena[11] = 7;

    elem = new Omega_eh(1, 0, 0, 12, ena); omega_eh_array().add(elem);

    } else if(i == 1) { // Omega_u

    double v[2]; Node *node;

    v[0] = 0.0; v[1] = 0.0; node = new Node(0, 2, v); node_array().add(node);

    v[0] = h_e_; node = new Node(1, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(2, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(3, 2, v); node_array().add(node);v[0] = 4.0*h_e_; node = new Node(4, 2, v); node_array().add(node);

    v[0] = 0.0; v[1] = 1.0*c_; node = new Node(5, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(6, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(7, 2, v); node_array().add(node);

    v[0] = 0.0; v[1] = 2.0*c_; node = new Node(8, 2, v); node_array().add(node);

    v[0] = h_e_; node = new Node(9, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(10, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(11, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(12, 2, v); node_array().add(node);

    int ena[8]; Omega_eh *elem;

    ena[0] = 0; ena[1] = 2; ena[2] = 10; ena[3] = 8; ena[4] = 1; ena[5] = 6; ena[6] = 9; ena[7] = 5;

    elem = new Omega_eh(0, 0, 0, 8, ena); omega_eh_array().add(elem);

    ena[0] = 2; ena[1] = 4; ena[2] = 12; ena[3] = 10; ena[4] = 3; ena[5] = 7; ena[6] = 11; ena[7] = 6;

    elem = new Omega_eh(1, 0, 0, 8, ena); omega_eh_array().add(elem);

    }

    }

    gh_on_Gamma_h_i::gh_on_Gamma_h_i(int i, int df, Omega_h& omega_h) : gh_on_Gamma_h() {

    gh_on_Gamma_h::__initialization(df, omega_h);

    if(i == 0) {

    for(int j = 8; j

  • 8/8/2019 Advanced Finite Element

    23/172

    Workbook of Applications in VectorSpace C++ Library 473

    Mixed and Hybrid Finite Element Methods

    Q 4/8 element definition

    diagonal A-matrix definition

    Serendipity shape functions for integra-

    ion and coordinate transformation

    Step 1: initial four corner nodes

    Step 2: add four edge nodes

    Step 3: correction of four corner nodes

    the presence of four edge nodes

    with four nodes at four Gaussintegration points

    N0-7 =0 (corresponding to geom. nodes)

    N8-11 = a

    N

    D-1

    off-diagonal C-matrix definition

    A D 1 ( ) de

    =

    class ElasticQ84_Mixed_Formulation : public Element_Formulation_Couple {

    public:

    ElasticQ84_Mixed_Formulation(Element_Type_Register a):Element_Formulation_Couple(a) {}

    Element_Formulation *make(int, Global_Discretization&);

    ElasticQ84_Mixed_Formulation(int, Global_Discretization&);

    Element_Formulation_Couple *make(int, Global_Discretization_Couple&);

    ElasticQ84_Mixed_Formulation(int, Global_Discretization_Couple&);

    };

    Element_Formulation* ElasticQ84_Mixed_Formulation::make(int en,Global_Discretization& gd){

    return new ElasticQ84_Mixed_Formulation(en,gd); }

    static const double a_ = E_ / (1-pow(v_,2));

    static const double Dv[3][3] = { {a_, a_*v_, 0.0 }, {a_*v_, a_, 0.0 }, {0.0, 0.0, a_*(1-v_)/2.0} };

    C0 D = MATRIX("int, int, const double*", 3, 3, Dv[0]);

    ElasticQ84_Mixed_Formulation::ElasticQ84_Mixed_Formulation(

    int en, Global_Discretization& gd) : Element_Formulation_Couple(en, gd) {Quadrature qp(2, 9);

    H1 Z(2, (double*)0, qp),

    N = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE(int, int, Quadrature", 8, 2, qp),

    Zai, Eta; Zai &= Z[0]; Eta &= Z[1];

    N[0] = (1.0-Zai)*(1.0-Eta)/4.0; N[1] = (1.0+Zai)*(1.0-Eta)/4.0;

    N[2] = (1.0+Zai)*(1.0+Eta)/4.0; N[3] = (1.0-Zai)*(1.0+Eta)/4.0;

    N[4] = (1.0-Zai.pow(2))*(1.0-Eta)/2.0; N[5] = (1.0-Eta.pow(2))*(1.0+Zai)/2.0;

    N[6] = (1.0-Zai.pow(2))*(1.0+Eta)/2.0; N[7] = (1.0-Eta.pow(2))*(1.0-Zai)/2.0;

    N[0] = N[0] - (N[4]+N[7])/2.0; N[1] = N[1] - (N[4]+N[5])/2.0;

    N[2] = N[2] - (N[5]+N[6])/2.0; N[3] = N[3] - (N[6]+N[7])/2.0;

    C0 x = MATRIX("int, int, C0&, int, int", 8, 2, xl, 0, 0);

    H1 X = N*x; J dv(d(X).det());

    double sqrt3 = sqrt(3.0); C0 zero(0.0);

    H0 n = INTEGRABLE_VECTOR("int, Quadrature", 4/*nen*/, qp), n8, n9, n10, n11;

    H0 zai, eta;

    zai &= ((H0)Z[0]); eta &= ((H0)Z[1]);

    n[0] = (1.0-sqrt3*zai)*(1.0-sqrt3*eta)/4.0; n[1] = (1.0+sqrt3*zai)*(1.0-sqrt3*eta)/4.0;

    n[2] = (1.0+sqrt3*zai)*(1.0+sqrt3*eta)/4.0; n[3] = (1.0-sqrt3*zai)*(1.0+sqrt3*eta)/4.0;

    n8 &= n[0]; n9 &= n[1]; n10 &= n[2]; n11 &= n[3];

    H0 N_sig = ( (n8 | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 | zero | zero ) &

    (zero | n8 | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 | zero ) &(zero |(zero | n8) | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 ));

    Matrix::Decomposition_Method = Matrix::Cholesky_Decomposition;

    C0 D_inv = D.inverse();

    Matrix::Decomposition_Method = Matrix::LU_Decomposition;

    stiff &= MATRIX("int, int", 36, 36);

    C0 stiff_sub = MATRIX("int, int, C0&, int, int", 12, 12, stiff, 24, 24);

    stiff_sub = -((~N_sig) * (D_inv * N_sig)) | dv;

    }

    Element_Formulation_Couple* ElasticQ84_Mixed_Formulation::make(

    int en, Global_Discretization_Couple& gdc) {return new ElasticQ84_Mixed_Formulation(en,gdc);

    }

    ElasticQ84_Mixed_Formulation::ElasticQ84_Mixed_Formulation(

    int en, Global_Discretization_Couple& gdc) : Element_Formulation_Couple(en, gdc) {

    Quadrature qp(2, 9);

    H1 Z(2, (double*)0, qp),

    N = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", 8, 2, qp),

    Zai, Eta;

    Zai &= Z[0]; Eta &= Z[1];

    N[0] = (1.0-Zai)*(1.0-Eta)/4.0; N[1] = (1.0+Zai)*(1.0-Eta)/4.0;N[2] = (1.0+Zai)*(1.0+Eta)/4.0; N[3] = (1.0-Zai)*(1.0+Eta)/4.0;

    Advanced Finite Element MethodsChapter 5

  • 8/8/2019 Advanced Finite Element

    24/172

    Advanced Finite Element Methods

    474 Workbook of Applications in VectorSpace C++ Library

    Chapter 5

    N[4] = (1.0-Zai.pow(2))*(1.0-Eta)/2.0; N[5] = (1.0-Eta.pow(2))*(1.0+Zai)/2.0;

    N[6] = (1.0-Zai.pow(2))*(1.0+Eta)/2.0; N[7] = (1.0-Eta.pow(2))*(1.0-Zai)/2.0;

    N[0] = N[0] - (N[4]+N[7])/2.0; N[1] = N[1] - (N[4]+N[5])/2.0;

    N[2] = N[2] - (N[5]+N[6])/2.0; N[3] = N[3] - (N[6]+N[7])/2.0;

    H1 X = N*xl;

    H0 Nx = d(N) * d(X).inverse();

    J dv(d(X).det());

    H0 w_x = INTEGRABLE_SUBMATRIX("int, int, H0&", 1, 2, Nx),

    wx, wy, B;

    wx &= w_x[0][0]; wy &= w_x[0][1];

    C0 zero(0.0);

    B &= (~wx || zero) &

    (zero || ~wy ) &

    (~wy || ~wx );

    double sqrt3 = sqrt(3.0);

    H0 n = INTEGRABLE_VECTOR("int, Quadrature", 12/*nen*/, qp),n8, n9, n10, n11, zai, eta;

    zai &= (H0)Z[0]; eta &= (H0)Z[1];

    n[0] = (1.0-sqrt3*zai)*(1.0-sqrt3*eta)/4.0; n[1] = (1.0+sqrt3*zai)*(1.0-sqrt3*eta)/4.0;

    n[2] = (1.0+sqrt3*zai)*(1.0+sqrt3*eta)/4.0; n[3] = (1.0-sqrt3*zai)*(1.0+sqrt3*eta)/4.0;

    n8 &= n[0]; n9 &= n[1]; n10 &= n[2]; n11 &= n[3];

    H0 N_sig = ((n8 | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 | zero | zero ) &

    (zero | n8 | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 | zero ) &

    (zero |(zero | n8) | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 ));

    stiff &= MATRIX("int, int", 16, 36);

    C0 stiff_sub = MATRIX("int, int, C0&, int, int", 16, 12, stiff, 0, 24);

    stiff_sub = ((~B)*N_sig) | dv;

    }

    Element_Formulation* Element_Formulation::type_list = 0;

    static Element_Type_Register element_type_register_instance;

    static ElasticQ84_Mixed_Formulation

    elasticq84_mixed_formulation_instance(element_type_register_instance);

    static Matrix_Representation mr(sigma_gd);

    static Matrix_Representation_Couple mrc(gdc, 0, 0, &(mr.rhs()), &mr);

    int main() {

    mr.assembly();

    mrc.assembly();C0 A = ((C0)(mr.lhs())), f_1 = ((C0)(mr.rhs())),

    C = ((C0)(mrc.lhs())), f_2 = ((C0)(mrc.rhs()));

    Cholesky dnH(-A);

    C0 Ainv = -(dnH.inverse());

    C0 CAinvCt = C*Ainv*(~C);

    LU dCAinvCt(CAinvCt);

    cout

  • 8/8/2019 Advanced Finite Element

    25/172

    Workbook of Applications in VectorSpace C++ Library 475

    Mixed and Hybrid Finite Element Methods

    Hu-Washizu Variational Principle

    In addition to Eq. 537 , the constitutive equations and the strain-displacement relations can be used such as

    = D , and = Lu Eq. 552The variational approximation to these two equations are

    Eq. 553

    Eq. 553 and Eq. 537 are the Euler-Lagange equations of the Lagrangian functional

    Eq. 554

    The Lagrangian functional in Eq. 554 is known as the Hu-Washizu variational principle. The finite element

    approximation to the strain field uses the interpolation functions (x) as

    Eq. 555

    The matrix form, at element level, ofEq. 537 and Eq. 553 is

    Eq. 556

    where

    Eq. 557

    Eq. 558

    Eq. 559

    Eq. 560

    T D ( ) d 0= and T Lu ( ) d

    0=,

    , u,( ) 12--- TD d

    T Lu( ) d

    uTb d

    uTh d

    h

    =

    e ea x( )ea

    A CT 0

    C 0 ET

    0 E 0

    u

    f1

    f2

    f3

    =

    A D( ) de

    =

    E B de=

    C de

    =

    f1

    A n

    ( )

    eCT n

    ( )

    e=

    Advanced Finite Element MethodsChapter 5

  • 8/8/2019 Advanced Finite Element

    26/172

    476 Workbook of Applications in VectorSpace C++ Library

    p

    Eq. 561

    Eq. 562

    The condition for non-singular matrices is1

    Eq. 563

    The Program Listing 55 implements Eq. 556 to Eq. 562 (project hu_washizu_variational_principle inproject workspace file fe.dsw). With the same patch test problem for the Hellinger-Reissner variational princi-

    ple in the previous section. We use shape functions with four nodes at Gaussian integration points for both stress

    () and strain () fields; i.e., = . This results in C-matrix in Eq. 559 to be symmetrical negative definitive.Care should be taken, if Cholesky decomposition is used, which is applicable to a symmetricalpositive defini-

    tive matrix. The displacement (u) shape function is an eight-nodes serendipity element. These choices satisfythe condition in Eq. 563. The coding of matrix substructuring technique supported by fe.lib becomes a little

    more elaborated with three-fields (, , u) instead of two-fields (, u).The modification from two-fields problem is minor, however. For the definitions of discretized global

    domain and boundary have three index entries as

    1 Omega_h_i::Omega_h_i(int i) : Omega_h(0) { // hi2 if(i == 0 || i == 1) { // h or

    h

    3 ...

    4 } else if(i == 2) { // hu

    5 ...6 }

    7 gh_on_Gamma_h_i::gh_on_Gamma_h_i(int i, int df, Omega_h& omega_h) : gh_on_Gamma_h() { //hi8 gh_on_Gamma_h::__initialization(df, omega_h);

    9 if(i == 0) { // h10 ...

    11 } else if(i == 1) { // h12 ...

    13 } else if(i == 2) { // hu

    14 ...

    15 }

    16 }

    The instantiation of global discretized couples are

    1. see discussion in p.333-334 in Zienkiewicz, O.C. and R.L. Taylor, 1989, The finite element method, 4th ed., vol. 1.McGraw-Hill, Inc., UK.

    f2 C n( ) e ETu

    eu

    =

    f3 b de n( ) d

    e E n( ) e+=

    n nu+ n and n nu,

    Mixed and Hybrid Finite Element Methods

  • 8/8/2019 Advanced Finite Element

    27/172

    Workbook of Applications in VectorSpace C++ Library 477

    define , and

    elem # 0 nodal coordinates

    1st Gauss point natural coordinates

    1st Gauss point physical coordinates

    2nd Gauss point natural coordinates

    2nd Gauss point physical coordinates

    3rd Gauss point natural coordinates3rd Gauss point physical coordinates

    4th Gauss point natural coordinates

    4th Gauss point physical coordinates

    elem # 1 nodal coordinates1st Gauss point natural coordinates

    1st Gauss point physical coordinates

    2nd Gauss point natural coordinates

    2nd Gauss point physical coordinates

    3rd Gauss point natural coordinates

    3rd Gauss point physical coordinates

    4th Gauss point natural coordinates

    4th Gauss point physical coordinates

    #include "include\fe.h"

    #include "include\omega_h_n.h"

    Matrix_Representation_Couple::assembly_switch Matrix_Representation_Couple::

    Assembly_Switch = Matrix_Representation_Couple::ALL;static const int row_node_no = 5; static const int row_segment_no = row_node_no-1;

    static const double L_ = 10.0; static const double c_ = 1.0;

    static const double h_e_ = L_/((double)row_segment_no);

    static const double E_ = 1.e3; static const double v_ = 0.3;

    Omega_h_i::Omega_h_i(int i) : Omega_h(0) {

    if(i == 0 || i == 1) {

    double inv_sqrt3 = 1.0/sqrt(3.0), v[2], xl[4][2], zai, eta;

    Node *node;

    xl[0][0] = 0.0; xl[0][1] = 0.0; xl[1][0] = 2.0*h_e_; xl[1][1] = 0.0;

    xl[2][0] = 2.0*h_e_; xl[2][1] = 2.0*c_; xl[3][0] = 0.0; xl[3][1] = 2.0*c_;

    zai = - inv_sqrt3; eta = - inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(0, 2, v); node_array().add(node);

    zai = inv_sqrt3; eta = - inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+(1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+(1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(1, 2, v); node_array().add(node);

    zai = inv_sqrt3; eta = inv_sqrt3;for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(2, 2, v); node_array().add(node);

    zai = - inv_sqrt3; eta = inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(3, 2, v); node_array().add(node);

    xl[0][0] = 2.0*h_e_; xl[0][1] = 0.0; xl[1][0] = 4.0*h_e_; xl[1][1] = 0.0;

    xl[2][0] = 4.0*h_e_; xl[2][1] = 2.0*c_; xl[3][0] = 2.0*h_e_; xl[3][1] = 2.0*c_;zai = - inv_sqrt3; eta = - inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(4, 2, v); node_array().add(node);

    zai = inv_sqrt3; eta = - inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(5, 2, v); node_array().add(node);zai = inv_sqrt3; eta = inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(6, 2, v); node_array().add(node);

    zai = - inv_sqrt3; eta = inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(7, 2, v); node_array().add(node);

    Advanced Finite Element MethodsChapter 5

  • 8/8/2019 Advanced Finite Element

    28/172

    478 Workbook of Applications in VectorSpace C++ Library

    geometrical nodes supply four corner

    nodes coordinates to the element level

    define elements

    first 8 nodes are geometrical nodeslast four nodes are real nodes

    u8-node serendipity element

    define nodes

    define elements

    B.C.disable all geometrical nodes

    B.C.disable all geometrical nodes

    Wu boundary condition

    Simpsons integration rule:

    {-15 *2/3, 0*4/3, 15*2./3}

    = {-5, 0, 5}

    v[0] = 0.0; v[1] = 0.0; node = new Node(8, 2, v); node_array().add(node);

    v[0] = 1.0*h_e_; node = new Node(9, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(10, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(11, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(12, 2, v); node_array().add(node);

    v[0] = 0.0; v[1] = 1.0*c_; node = new Node(13, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(14, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(15, 2, v); node_array().add(node);

    v[0] = 0.0; v[1] = 2.0*c_; node = new Node(16, 2, v); node_array().add(node);

    v[0] = 1.0*h_e_; node = new Node(17, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(18, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(19, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(20, 2, v); node_array().add(node);

    int ena[12]; Omega_eh *elem;

    ena[0] = 8; ena[1] = 10; ena[2] = 18; ena[3] = 16; ena[4] = 9; ena[5] = 14;

    ena[6] = 17; ena[7] = 13; ena[8] = 0; ena[9] = 1; ena[10] = 2; ena[11] = 3;elem = new Omega_eh(0, 0, 0, 12, ena); omega_eh_array().add(elem);

    ena[0] = 10; ena[1] = 12; ena[2] = 20; ena[3] = 18; ena[4] = 11; ena[5] = 15;

    ena[6] = 19; ena[7] = 14; ena[8] = 4; ena[9] = 5; ena[10] = 6; ena[11] = 7;

    elem = new Omega_eh(1, 0, 0, 12, ena); omega_eh_array().add(elem);

    } else if(i == 2) {

    double v[2]; Node *node;

    v[0] = 0.0; v[1] = 0.0; node = new Node(0, 2, v); node_array().add(node);

    v[0] = h_e_; node = new Node(1, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(2, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(3, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(4, 2, v); node_array().add(node);v[0] = 0.0; v[1] = 1.0*c_; node = new Node(5, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(6, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(7, 2, v); node_array().add(node);

    v[0] = 0.0; v[1] = 2.0*c_; node = new Node(8, 2, v); node_array().add(node);

    v[0] = h_e_; node = new Node(9, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(10, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(11, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(12, 2, v); node_array().add(node);

    int ena[8]; Omega_eh *elem;

    ena[0] = 0; ena[1] = 2; ena[2] = 10; ena[3] = 8; ena[4] = 1; ena[5] = 6; ena[6] = 9; ena[7] = 5;

    elem = new Omega_eh(0, 0, 0, 8, ena); omega_eh_array().add(elem);

    ena[0] = 2; ena[1] = 4; ena[2] = 12; ena[3] = 10; ena[4] = 3; ena[5] = 7; ena[6] = 11; ena[7] = 6;

    elem = new Omega_eh(1, 0, 0, 8, ena); omega_eh_array().add(elem);

    }

    }

    gh_on_Gamma_h_i::gh_on_Gamma_h_i(int i, int df, Omega_h& omega_h) : gh_on_Gamma_h() {

    gh_on_Gamma_h::__initialization(df, omega_h);

    if(i == 0) {

    for(int j = 8; j

  • 8/8/2019 Advanced Finite Element

    29/172

    Workbook of Applications in VectorSpace C++ Library 479

    g.d. for defining A matrixh = {x, y, }T

    h = {x, y, }T

    u , uh = {u, v}T

    g.d. u for defining irreducible K matrix

    g.d.couple {-} for defining C matrix

    g.d.couple {u-} for defining E matrix

    diagonals A & K matrices

    off-diagonals C & E matrices

    diagonals matrices

    A matrix formulation

    eight nodes serendipity shape function

    h = {x, y, }T

    K matrix; for iterative method to esti-

    mate initial u values

    A D( ) de

    =

    static const int epsilon_ndf = 3; static Omega_h_i oh_epsilon(0);

    static gh_on_Gamma_h_i epsilon_gh(0, epsilon_ndf, oh_epsilon);

    static U_h epsilon_h(epsilon_ndf, oh_epsilon);

    static Global_Discretization *epsilon_type = new Global_Discretization;

    static Global_Discretization epsilon_gd(oh_epsilon, epsilon_gh, epsilon_h, epsilon_type);

    static const int sigma_ndf = 3; static Omega_h_i oh_sigma(1);static gh_on_Gamma_h_i sigma_gh(1, sigma_ndf, oh_sigma);

    static U_h sigma_h(sigma_ndf, oh_sigma);

    static Global_Discretization sigma_gd(oh_sigma, sigma_gh, sigma_h);

    static const int u_ndf = 2; static Omega_h_i oh_u(2);

    static gh_on_Gamma_h_i u_gh(2, u_ndf, oh_u); static U_h u_h(u_ndf, oh_u);

    static Global_Discretization *u_type = new Global_Discretization;

    static Global_Discretization u_gd(oh_u, u_gh, u_h, u_type);

    static Global_Discretization_Couple *sigma_epsilon = new Global_Discretization_Couple();

    static Global_Discretization_Couple gdc_sigma_epsilon(sigma_gd, epsilon_gd, sigma_epsilon);

    static Global_Discretization_Couple *u_sigma = new Global_Discretization_Couple();

    static Global_Discretization_Couple gdc_u_sigma(u_gd, sigma_gd, u_sigma);

    class ElasticQ84_Mixed_Formulation : public Element_Formulation_Couple {

    public:

    ElasticQ84_Mixed_Formulation(Element_Type_Register a):Element_Formulation_Couple(a) {}

    Element_Formulation *make(int, Global_Discretization&);

    ElasticQ84_Mixed_Formulation(int, Global_Discretization&);

    Element_Formulation_Couple *make(int, Global_Discretization_Couple&);

    ElasticQ84_Mixed_Formulation(int, Global_Discretization_Couple&);

    };

    Element_Formulation* ElasticQ84_Mixed_Formulation::make(

    int en,Global_Discretization& gd) { return new ElasticQ84_Mixed_Formulation(en,gd); }static const double a_ = E_ / (1-pow(v_,2));

    static const double Dv[3][3] = { {a_, a_*v_, 0.0 }, {a_*v_, a_, 0.0}, {0.0, 0.0, a_*(1-v_)/2.0} };

    C0 D = MATRIX("int, int, const double*", 3, 3, Dv[0]);

    ElasticQ84_Mixed_Formulation::ElasticQ84_Mixed_Formulation(

    int en, Global_Discretization& gd) : Element_Formulation_Couple(en, gd) {

    if(gd.type() == epsilon_type) {

    Quadrature qp(2, 9);

    H1 Z(2, (double*)0, qp), Zai, Eta,

    N = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", 8, 2, qp);

    Zai &= Z[0]; Eta &= Z[1];

    N[0] = (1.0-Zai)*(1.0-Eta)/4.0; N[1] = (1.0+Zai)*(1.0-Eta)/4.0;

    N[2] = (1.0+Zai)*(1.0+Eta)/4.0; N[3] = (1.0-Zai)*(1.0+Eta)/4.0;

    N[4] = (1.0-Zai.pow(2))*(1.0-Eta)/2.0; N[5] = (1.0-Eta.pow(2))*(1.0+Zai)/2.0;

    N[6] = (1.0-Zai.pow(2))*(1.0+Eta)/2.0; N[7] = (1.0-Eta.pow(2))*(1.0-Zai)/2.0;

    N[0] = N[0] - (N[4]+N[7])/2.0; N[1] = N[1] - (N[4]+N[5])/2.0;

    N[2] = N[2] - (N[5]+N[6])/2.0; N[3] = N[3] - (N[6]+N[7])/2.0;

    C0 x = MATRIX("int, int, C0&, int, int", 8, 2, xl, 0, 0);

    H1 X = N*x; J dv(d(X).det()); double sqrt3 = sqrt(3.0); C0 zero(0.0);

    H0 n = INTEGRABLE_VECTOR("int, Quadrature", 4, qp), n8, n9, n10, n11, zai, eta;

    zai &= ((H0)Z[0]); eta &= ((H0)Z[1]);

    n[0] = (1.0-sqrt3*zai)*(1.0-sqrt3*eta)/4.0; n[1] = (1.0+sqrt3*zai)*(1.0-sqrt3*eta)/4.0;n[2] = (1.0+sqrt3*zai)*(1.0+sqrt3*eta)/4.0; n[3] = (1.0-sqrt3*zai)*(1.0+sqrt3*eta)/4.0;

    n8 &= n[0]; n9 &= n[1]; n10 &= n[2]; n11 &= n[3];

    H0 N_epsilon = ((n8 | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 | zero | zero ) &

    (zero | n8 | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 | zero ) &

    (zero |(zero | n8) | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 ));

    stiff &= MATRIX("int, int", 36, 36);

    C0 stiff_sub = MATRIX("int, int, C0&, int, int", 12, 12, stiff, 24, 24);

    stiff_sub = ((~N_epsilon) * (D * N_epsilon)) | dv;

    } else {

    Quadrature qp(2, 9);

    H1 Z(2, (double*)0, qp), , Zai, Eta

    N = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE( "int, int, Quadrature", 8, 2, qp);

    Advanced Finite Element MethodsChapter 5

  • 8/8/2019 Advanced Finite Element

    30/172

    480 Workbook of Applications in VectorSpace C++ Library

    K is a standard stiffness matrix

    off-diagonal matrices

    C matrux formulation

    h

    = {x, y, }T

    E matrux formulation

    C de

    =

    Zai &= Z[0]; Eta &= Z[1];

    N[0] = (1.0-Zai)*(1.0-Eta)/4.0; N[1] = (1.0+Zai)*(1.0-Eta)/4.0;

    N[2] = (1.0+Zai)*(1.0+Eta)/4.0; N[3] = (1.0-Zai)*(1.0+Eta)/4.0;

    N[4] = (1.0-Zai.pow(2))*(1.0-Eta)/2.0; N[5] = (1.0-Eta.pow(2))*(1.0+Zai)/2.0;

    N[6] = (1.0-Zai.pow(2))*(1.0+Eta)/2.0; N[7] = (1.0-Eta.pow(2))*(1.0-Zai)/2.0;

    N[0] -= (N[4]+N[7])/2.0; N[1] -= (N[4]+N[5])/2.0;N[2] -= (N[5]+N[6])/2.0; N[3] -= (N[6]+N[7])/2.0;

    H1 X = N*xl; H0 Nx = d(N) * d(X).inverse(); J dv(d(X).det());

    H0 w_x = INTEGRABLE_SUBMATRIX("int, int, H0&", 1, 2, Nx), wx, wy, B;

    wx &= w_x[0][0]; wy &= w_x[0][1]; C0 zero(0.0);

    B &= (~wx || zero) & (zero || ~wy ) & (~wy || ~wx );

    stiff &= ((~B)*D*B)|dv;

    }

    }

    Element_Formulation_Couple* ElasticQ84_Mixed_Formulation::make(int en,

    Global_Discretization_Couple& gdc) { return new ElasticQ84_Mixed_Formulation(en,gdc); }ElasticQ84_Mixed_Formulation::ElasticQ84_Mixed_Formulation(int en,

    Global_Discretization_Couple& gdc) : Element_Formulation_Couple(en, gdc) {

    if(gdc.type() == sigma_epsilon) {

    Quadrature qp(2, 9);

    H1 Z(2, (double*)0, qp), Zai, Eta,

    N = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature",8,2, qp);

    Zai &= Z[0]; Eta &= Z[1];

    N[0] = (1.0-Zai)*(1.0-Eta)/4.0; N[1] = (1.0+Zai)*(1.0-Eta)/4.0;

    N[2] = (1.0+Zai)*(1.0+Eta)/4.0; N[3] = (1.0-Zai)*(1.0+Eta)/4.0;

    N[4] = (1.0-Zai.pow(2))*(1.0-Eta)/2.0; N[5] = (1.0-Eta.pow(2))*(1.0+Zai)/2.0;

    N[6] = (1.0-Zai.pow(2))*(1.0+Eta)/2.0; N[7] = (1.0-Eta.pow(2))*(1.0-Zai)/2.0;N[0] = N[0] - (N[4]+N[7])/2.0; N[1] = N[1] - (N[4]+N[5])/2.0;

    N[2] = N[2] - (N[5]+N[6])/2.0; N[3] = N[3] - (N[6]+N[7])/2.0;

    H1 X = N*xl; J dv(d(X).det());

    double sqrt3 = sqrt(3.0); C0 zero(0.0);

    H0 n = INTEGRABLE_VECTOR("int, Quadrature", 4, qp), n8, n9, n10, n11, zai, eta;

    zai &= ((H0)Z[0]); eta &= ((H0)Z[1]);

    n[0] = (1.0-sqrt3*zai)*(1.0-sqrt3*eta)/4.0; n[1] = (1.0+sqrt3*zai)*(1.0-sqrt3*eta)/4.0;

    n[2] = (1.0+sqrt3*zai)*(1.0+sqrt3*eta)/4.0; n[3] = (1.0-sqrt3*zai)*(1.0+sqrt3*eta)/4.0;

    n8 &= n[0]; n9 &= n[1]; n10 &= n[2]; n11 &= n[3];

    H0 N_sig = ((n8 | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 | zero | zero ) &

    (zero | n8 | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 | zero ) &

    (zero |(zero | n8) | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 ));

    H0 N_epsilon; N_epsilon &= N_sig;

    stiff &= MATRIX("int, int", 36, 36);

    C0 stiff_sub = MATRIX("int, int, C0&, int, int", 12, 12, stiff, 24, 24);

    stiff_sub = -((~N_sig)*N_epsilon) | dv;

    } else {

    Quadrature qp(2, 9);

    H1 Z(2, (double*)0, qp), Zai, Eta,

    N = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE( "int, int, Quadrature",8,2, qp);

    Zai &= Z[0]; Eta &= Z[1];N[0] = (1.0-Zai)*(1.0-Eta)/4.0; N[1] = (1.0+Zai)*(1.0-Eta)/4.0;

    N[2] = (1.0+Zai)*(1.0+Eta)/4.0; N[3] = (1.0-Zai)*(1.0+Eta)/4.0;

    N[4] = (1.0-Zai.pow(2))*(1.0-Eta)/2.0; N[5] = (1.0-Eta.pow(2))*(1.0+Zai)/2.0;

    N[6] = (1.0-Zai.pow(2))*(1.0+Eta)/2.0; N[7] = (1.0-Eta.pow(2))*(1.0-Zai)/2.0;

    N[0] = N[0] - (N[4]+N[7])/2.0; N[1] = N[1] - (N[4]+N[5])/2.0;

    N[2] = N[2] - (N[5]+N[6])/2.0; N[3] = N[3] - (N[6]+N[7])/2.0;

    H1 X = N*xl; H0 Nx = d(N) * d(X).inverse(); J dv(d(X).det());

    H0 w_x = INTEGRABLE_SUBMATRIX("int, int, H0&", 1, 2, Nx), wx, wy, B;

    wx &= w_x[0][0]; wy &= w_x[0][1]; C0 zero(0.0);

    B &= (~wx || zero) &

    (zero || ~wy ) &

    (~wy || ~wx );

    Mixed and Hybrid Finite Element Methods

  • 8/8/2019 Advanced Finite Element

    31/172

    Workbook of Applications in VectorSpace C++ Library 481

    double sqrt3 = sqrt(3.0);

    H0 n = INTEGRABLE_VECTOR("int, Quadrature", 4, qp), n8, n9, n10, n11, zai, eta;

    zai &= ((H0)Z[0]); eta &= ((H0)Z[1]);

    n[0] = (1.0-sqrt3*zai)*(1.0-sqrt3*eta)/4.0; n[1] = (1.0+sqrt3*zai)*(1.0-sqrt3*eta)/4.0;

    n[2] = (1.0+sqrt3*zai)*(1.0+sqrt3*eta)/4.0; n[3] = (1.0-sqrt3*zai)*(1.0+sqrt3*eta)/4.0;

    n8 &= n[0]; n9 &= n[1]; n10 &= n[2]; n11 &= n[3];H0 N_sig = ((n8 | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 | zero | zero ) &

    (zero | n8 | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 | zero ) &

    (zero |(zero | n8) | zero | zero | n9 | zero | zero | n10 | zero | zero | n11 ));

    stiff &= MATRIX("int, int", 16, 36);

    C0 stiff_sub = MATRIX("int, int, C0&, int, int", 16, 12, stiff, 0, 24);

    stiff_sub = ((~B)*N_sig) | dv;

    }

    }

    Element_Formulation* Element_Formulation::type_list = 0;

    static Element_Type_Register element_type_register_instance;

    static ElasticQ84_Mixed_Formulation

    elasticq84_mixed_formulation_instance(element_type_register_instance);

    static Matrix_Representation mr(epsilon_gd);

    static Matrix_Representation_Couple mrcC(gdc_sigma_epsilon, 0, 0, &(mr.rhs()), &mr);

    static Matrix_Representation_Couple mrcE(gdc_u_sigma, 0, 0, &(mrcC.rhs()), &mrcC);

    int main() {

    mrcC.assembly();

    mr.assembly();

    mrcE.assembly();

    C0 A = ((C0)(mr.lhs())),

    f_1 = ((C0)(mr.rhs())),C = ((C0)(mrcC.lhs())),

    f_2 = ((C0)(mrcC.rhs())),

    E = ((C0)(mrcE.lhs())),

    f_3 = ((C0)(mrcE.rhs()));

    Cholesky dnC(-C);

    C0 Cinv = -(dnC.inverse()),

    CinvA = Cinv*A,

    CinvACinv = Cinv*A*Cinv,

    ECinvACinv = E*CinvACinv,

    ECinvACinvEt = ECinvACinv*(~E);

    Cholesky dECinvACinvEt(ECinvACinvEt);

    C0 u = dECinvACinvEt * (f_3 - (E*Cinv)*f_1 + ECinvACinv*f_2);

    C0 epsilon = -(dnC*(f_2-(~E)*u));

    C0 sigma = -(dnC*(f_1-A*epsilon));

    epsilon_h = epsilon;

    epsilon_h = epsilon_gd.gh_on_gamma_h();

    cout

  • 8/8/2019 Advanced Finite Element

    32/172

    482 Workbook of Applications in VectorSpace C++ Library

    1 static const int epsilon_ndf = 3; // ndf 2 static Omega_h_i oh_epsilon(0); // h3 static gh_on_Gamma_h_i epsilon_gh(0, epsilon_ndf, oh_epsilon); // h4 static U_h epsilon_h(epsilon_ndf, oh_epsilon); // x, yxy5 static Global_Discretization *epsilon_type = new Global_Discretization;

    6 static Global_Discretization epsilon_gd(oh_epsilon, epsilon_gh, epsilon_h, epsilon_type);

    7 static const int sigma_ndf = 3; // ndf 8 static Omega_h_i oh_sigma(1); // h9 static gh_on_Gamma_h_i sigma_gh(1, sigma_ndf, oh_sigma); // h10 static U_h sigma_h(sigma_ndf, oh_sigma); // x, yxy11 static Global_Discretization sigma_gd(oh_sigma, sigma_gh, sigma_h);

    12 static const int u_ndf = 2; // ndf u

    13 static Omega_h_i oh_u(2); // hu14 static gh_on_Gamma_h_i u_gh(2, u_ndf, oh_u); // hu15 static U_h u_h(u_ndf, oh_u); // ux, uy16 static Global_Discretization *u_type = new Global_Discretization;

    17 static Global_Discretization u_gd(oh_u, u_gh, u_h, u_type);

    18 static Global_Discretization_Couple *sigma_epsilon = new Global_Discretization_Couple(); //19 static Global_Discretization_Couple gdc_sigma_epsilon(sigma_gd, epsilon_gd, sigma_epsilon);

    20 static Global_Discretization_Couple *u_sigma = new Global_Discretization_Couple(); // u-

    21 static Global_Discretization_Couple gdc_u_sigma(u_gd, sigma_gd, u_sigma);

    Three pointers to Global_Discretization and Global_Discretization_Coupe, epsilon_type, u_type, and

    sigma_epsilon, are to be used in Element_Formulation class definitions to switch to corresponding segments of

    submatrices definitions.

    1 class ElasticQ84_Mixed_Formulation : public Element_Formulation_Couple {

    2 public:3 ElasticQ84_Mixed_Formulation(Element_Type_Register a) : Element_Formulation_Couple(a) {}

    4 Element_Formulation *make(int, Global_Discretization&); // diagonal submatrices

    5 ElasticQ84_Mixed_Formulation(int, Global_Discretization&);

    6 Element_Formulation_Couple *make(int, Global_Discretization_Couple&);// off-diagonal submatrices

    7 ElasticQ84_Mixed_Formulation(int, Global_Discretization_Couple&);

    8 };

    9 Element_Formulation* ElasticQ84_Mixed_Formulation::make(int en, Global_Discretization& gd) {

    10 return new ElasticQ84_Mixed_Formulation(en,gd);11 }

    12 ElasticQ84_Mixed_Formulation::ElasticQ84_Mixed_Formulation(int en, Global_Discretization& gd) :

    13 Element_Formulation_Couple(en, gd) {

    14 if(gd.type() == epsilon_type) { // define A-Matrix; field15 ...

    16 } else { //K-matrix; u-field, for iterative method to estimate initial u values, Z&T p. 361, Eq. 12.99

    17 ...

    18 }19 }

    Mixed and Hybrid Finite Element Methods

  • 8/8/2019 Advanced Finite Element

    33/172

    Workbook of Applications in VectorSpace C++ Library 483

    20 Element_Formulation_Couple* ElasticQ84_Mixed_Formulation::make(

    21 int en, Global_Discretization_Couple& gdc) { return new ElasticQ84_Mixed_Formulation(en,gdc); }

    22 ElasticQ84_Mixed_Formulation::ElasticQ84_Mixed_Formulation(

    23 int en, Global_Discretization_Couple& gdc) : Element_Formulation_Couple(en, gdc) {

    24 if(gdc.type() == sigma_epsilon) { // define C-Matrix; fields25 ...

    26 } else { // define E-matrix; u- fields27 ...

    28 }

    29 }

    Line 16 is to construct the convergence acceleration matrix if iterative method is used.1 The global solution is

    proceeded with to be solved first as

    = (EC-1 AC-1 ET)-1 (f3 - EC-1 f1 + EC

    -1 AC-1 f2) Eq. 564

    After is obtained, we can substituting in the following equation

    = C-1 (f2 - ET ) Eq. 565

    Then, is solved by substituting in

    = C-1 (f1 - A ) Eq. 566

    The Matrix_Representations are in instantiated in the followings with the global substructuring solution

    1 int main() {

    2 Matrix_Representation mr(epsilon_gd);

    3 Matrix_Representation_Couple mrcC(gdc_sigma_epsilon, 0, 0, &(mr.rhs()), &mr);

    4 Matrix_Representation_Couple mrcE(gdc_u_sigma, 0, 0, &(mrcC.rhs()), &mrcC);

    5 mrcC.assembly();

    6 mr.assembly();

    7 mrcE.assembly();

    8 C0 A = ((C0)(mr.lhs())), f_1 = ((C0)(mr.rhs())),

    9 C = ((C0)(mrcC.lhs())), f_2 = ((C0)(mrcC.rhs())),

    10 E = ((C0)(mrcE.lhs())), f_3 = ((C0)(mrcE.rhs()));

    11 Cholesky dnC(-C); // decomposition; C is symmetrical negative definite

    12 C0 Cinv = -(dnC.inverse()); // = (EC-1AC-1ET)-1 (f3-EC-1f1+ EC

    -1AC-1f2)

    13 C0 CinvA = Cinv*A;

    14 C0 CinvACinv = CinvA*Cinv;

    1. see next section and p. 361 in Zienkiewicz, O.C. and R.L. Taylor, 1989, The finite element method, 4th ed., vol. 1.McGraw-Hill, Inc., UK.

    u

    u

    u u

    u

    u

    Advanced Finite Element MethodsChapter 5

  • 8/8/2019 Advanced Finite Element

    34/172

    484 Workbook of Applications in VectorSpace C++ Library

    15 C0 ECinvACinv = E*CinvACinv;

    16 C0 ECinvACinvEt = ECinvACinv*(~E);

    17 Cholesky dECinvACinvEt(ECinvACinvEt);

    18 C0 u = dECinvACinvEt * (f_3 - (E*Cinv)*f_1 + ECinvACinv*f_2);

    19 C0 epsilon = -(dnC*(f_2-(~E)*u)); // = C-1(f2-ET )

    20 C0 sigma = -(dnC*(f_1-A*epsilon)); // = C-1(f1-A )

    21 epsilon_h = epsilon; // update free degree of freedom

    22 epsilon_h = epsilon_gd.gh_on_gamma_h(); // update fixed degree of freedom

    23 cout

  • 8/8/2019 Advanced Finite Element

    35/172

    Advanced Finite Element MethodsChapter 5

  • 8/8/2019 Advanced Finite Element

    36/172

    486 Workbook of Applications in VectorSpace C++ Library

    , and Eq. 576

    Substituting into Eq. 575 and Eq. 572 gives in matrix form at element level is

    Eq. 577

    where

    Eq. 578

    Eq. 579

    Eq. 580

    Eq. 581

    Eq. 582

    The solution to substructuring ofEq. 577 is proceeded from its second equation, using symmetrical negative

    definitiveness ofV,

    Eq. 583

    Substituting into the first equation ofEq. 577 gives

    Eq. 584

    That is,

    Eq. 585

    Therefore, we first solve , and then substituting back to Eq. 583 for recovering . Program Listing 56

    (project incompressible_u_p_formulation in project workspace file fe.dsw) implements the Q 4/9 element

    (with an additional center u-node) and test problem in the higher-order patch test.

    u Nuu= p Npp=

    A CT

    C V

    u

    p

    f1

    f2

    =

    A BT D02

    3---m m Bd

    e

    =

    C mNp( )TBd

    e

    =

    VNp Np

    K---------------------d

    e

    =

    f1 NuTb d

    e

    NuTt de

    Au e CTp e

    +=

    f2 Cu eVp e

    =

    p V 1 f2 Cu( )=

    Au CTV 1 f2 Cu( )+ f1=

    u A CTV 1 C[ ] 1 f1 CTV 1 f2[ ]=

    u u p

    Mixed and Hybrid Finite Element Methods

  • 8/8/2019 Advanced Finite Element

    37/172

    Workbook of Applications in VectorSpace C++ Library 487

    plane stress modification

    define u1st row

    2nd row

    3rd row

    Lagrangian 9-nodes element

    define pelem # 0 nodal coordinates

    1st Gauss point natural coordinates

    1st Gauss point physical coordinates

    2nd Gauss point natural coordinates

    2nd Gauss point physical coordinates

    3rd Gauss point natural coordinates

    3rd Gauss point physical coordinates

    4th Gauss point natural coordinates

    4th Gauss point physical coordinates

    #include "include\fe.h"

    #include "include\omega_h_n.h"

    Matrix_Representation_Couple::assembly_switch

    Matrix_Representation_Couple::Assembly_Switch = Matrix_Representation_Couple::ALL;

    static const int row_node_no = 5; static const int row_segment_no = row_node_no-1;

    static const double L_ = 10.0; static const double c_ = 1.0;

    static const double h_e_ = L_/((double)row_segment_no); // half element size

    static const double E_ = 1.e3; static const double v_ = 0.3;

    static const double lambda_ = v_*E_/((1+v_)*(1-2*v_));

    static const double mu_ = E_/(2*(1+v_));

    static const double lambda_bar = 2*lambda_*mu_/(lambda_+2*mu_);

    static const double K_ = lambda_bar+2.0/3.0*mu_;

    Omega_h_i::Omega_h_i(int i) : Omega_h(0) {

    if(i == 0) { double v[2]; Node *node;

    v[0] = 0.0; v[1] = 0.0; node = new Node(0, 2, v); node_array().add(node);

    v[0] = h_e_; node = new Node(1, 2, v); node_array().add(node);v[0] = 2.0*h_e_; node = new Node(2, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(3, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(4, 2, v); node_array().add(node);

    v[0] = 0.0; v[1] = 1.0*c_; node = new Node(5, 2, v); node_array().add(node);

    v[0] = 1.0*h_e_; node = new Node(6, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(7, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(8, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(9, 2, v); node_array().add(node);

    v[0] = 0.0; v[1] = 2.0*c_; node = new Node(10, 2, v); node_array().add(node);

    v[0] = h_e_; node = new Node(11, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(12, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(13, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(14, 2, v); node_array().add(node);

    int ena[9]; Omega_eh *elem;

    ena[0] = 0; ena[1] = 2; ena[2] = 12; ena[3] = 10; ena[4] = 1;

    ena[5] = 7; ena[6] = 11; ena[7] = 5; ena[8] = 6;

    elem = new Omega_eh(0, 0, 0, 9, ena); omega_eh_array().add(elem);

    ena[0] = 2; ena[1] = 4; ena[2] = 14; ena[3] = 12; ena[4] = 3;

    ena[5] = 9; ena[6] = 13; ena[7] = 7; ena[8] = 8;

    elem = new Omega_eh(1, 0, 0, 9, ena); omega_eh_array().add(elem);

    } else if(i == 1) { double inv_sqrt3 = 1.0/sqrt(3.0), v[2], xl[4][2], zai, eta; Node *node;xl[0][0] = 0.0; xl[0][1] = 0.0; xl[1][0] = 2.0*h_e_; xl[1][1] = 0.0;

    xl[2][0] = 2.0*h_e_; xl[2][1] = 2.0*c_; xl[3][0] = 0.0; xl[3][1] = 2.0*c_;

    zai = - inv_sqrt3; eta = - inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(0, 2, v); node_array().add(node);

    zai = inv_sqrt3; eta = - inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(1, 2, v); node_array().add(node);

    zai = inv_sqrt3; eta = inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(2, 2, v); node_array().add(node);

    zai = - inv_sqrt3; eta = inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];node = new Node(3, 2, v); node_array().add(node);

    Advanced Finite Element MethodsChapter 5

    elem # 1 nodal coordinatesxl[0][0] = 2 0*h e ; xl[0][1] = 0 0; xl[1][0] = 4 0*h e ; xl[1][1] = 0 0;

  • 8/8/2019 Advanced Finite Element

    38/172

    488 Workbook of Applications in VectorSpace C++ Library

    elem # 1 nodal coordinates

    1st Gauss point natural coordinates

    1st Gauss point physical coordinates

    2nd Gauss point natural coordinates

    2nd Gauss point physical coordinates

    3rd Gauss point natural coordinates

    3rd Gauss point physical coordinates

    4th Gauss point natural coordinates

    4th Gauss point physical coordinates

    geometrical nodes

    last four nodes are real pressure-field

    nodes

    Dirichlet B.C.

    Nuemann B.C.

    disable all geometrical nodes

    xl[0][0] = 2.0 h_e_; xl[0][1] = 0.0; xl[1][0] = 4.0 h_e_; xl[1][1] = 0.0;

    xl[2][0] = 4.0*h_e_; xl[2][1] = 2.0*c_; xl[3][0] = 2.0*h_e_; xl[3][1] = 2.0*c_;

    zai = - inv_sqrt3; eta = - inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];node = new Node(4, 2, v); node_array().add(node);

    zai = inv_sqrt3; eta = - inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(5, 2, v); node_array().add(node);

    zai = inv_sqrt3; eta = inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(6, 2, v); node_array().add(node);

    zai = - inv_sqrt3; eta = inv_sqrt3;

    for(int j = 0; j < 2; j++)

    v[j] = (1.0-zai)*(1.0-eta)/4.0*xl[0][j]+ (1.0+zai)*(1.0-eta)/4.0*xl[1][j]+

    (1.0+zai)*(1.0+eta)/4.0*xl[2][j]+ (1.0-zai)*(1.0+eta)/4.0*xl[3][j];

    node = new Node(7, 2, v); node_array().add(node);

    v[0] = 0.0; v[1] = 0.0; node = new Node(8, 2, v); node_array().add(node);

    v[0] = 1.0*h_e_; node = new Node(9, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(10, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(11, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(12, 2, v); node_array().add(node);v[0] = 0.0; v[1] = 1.0*c_; node = new Node(13, 2, v); node_array().add(node);

    v[0] = 1.0*h_e_; node = new Node(14, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(15, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(16, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(17, 2, v); node_array().add(node);

    v[0] = 0.0; v[1] = 2.0*c_; node = new Node(18, 2, v); node_array().add(node);

    v[0] = 1.0*h_e_; node = new Node(19, 2, v); node_array().add(node);

    v[0] = 2.0*h_e_; node = new Node(20, 2, v); node_array().add(node);

    v[0] = 3.0*h_e_; node = new Node(21, 2, v); node_array().add(node);

    v[0] = 4.0*h_e_; node = new Node(22, 2, v); node_array().add(node);

    int ena[13]; Omega_eh *elem;

    ena[0] = 8; ena[1] = 10; ena[2] = 20; ena[3] = 18; ena[4] = 9; ena[5] = 15;

    ena[6] = 19; ena[7] = 13; ena[8] = 14; ena[9] = 0; ena[10] = 1; ena[11] = 2; ena[12] = 3;

    elem = new Omega_eh(0, 0, 0, 13, ena); omega_eh_array().add(elem);

    ena[0] = 10; ena[1] = 12; ena[2] = 22; ena[3] = 20; ena[4] = 11; ena[5] = 17;

    ena[6] = 21; ena[7] = 15; ena[8] = 16; ena[9] = 4; ena[10] = 5; ena[11] = 6; ena[12] = 7;

    elem = new Omega_eh(1, 0, 0, 13, ena); omega_eh_array().add(elem);

    }

    }

    gh_on_Gamma_h_i::gh_on_Gamma_h_i(int i, int df, Omega_h& omega_h) : gh_on_Gamma_h() {

    gh_on_Gamma_h::__initialization(df, omega_h);if(i == 0) {

    the_gh_array[node_order(4)](0) = the_gh_array[node_order(9)](0) =

    the_gh_array[node_order(14)](0)=the_gh_array[node_order(9)](1)=

    gh_on_Gamma_h::Dirichlet;

    the_gh_array[node_order(10)][0] = -5.0; the_gh_array[node_order(0)][0] = 5.0;

    } else if(i == 1) {

    for(int j = 8; j

  • 8/8/2019 Advanced Finite Element

    39/172

    Workbook of Applications in VectorSpace C++ Library 489

    u

    u = [u, v]T

    p

    {p-u} global discretization couple

    diagonal submatrices

    Lagragian 9-node element

    A BT D02

    3---m m Bd

    e

    =

    VNp Np

    K---------------------d

    e

    =

    static gh_on_Gamma_h_i u_gh(0, u_ndf, oh_u); static U_h u_h(u_ndf, oh_u);

    static const int p_ndf = 1; static Omega_h_i oh_p(1);

    static gh_on_Gamma_h_i p_gh(1, p_ndf, oh_p); static U_h p_h(p_ndf, oh_p);

    static Global_Discretization *u_type = new Global_Discretization;

    static Global_Discretization u_gd(oh_u, u_gh, u_h, u_type);static Global_Discretization *p_type = new Global_Discretization;

    static Global_Discretization p_gd(oh_p, p_gh, p_h, p_type);

    static Global_Discretization_Couple *p_u_type = new Global_Discretization_Couple;

    static Global_Discretization_Couple gdc(p_gd, u_gd, p_u_type);

    class Incompressible_ElasticQ94_Mixed_Formulation : public Element_Formulation_Couple {

    public:

    Incompressible_ElasticQ94_Mixed_Formulation(Element_Type_Register a) :

    Element_Formulation_Couple(a) {}

    Element_Formulation *make(int, Global_Discretization&);

    Incompressible_ElasticQ94_Mixed_Formulation(int, Global_Discretization&);

    Element_Formulation_Couple *make(int, Global_Discretization_Couple&);

    Incompressible_ElasticQ94_Mixed_Formulation(int, Global_Discretization_Couple&);

    };

    Element_Formulation*

    Incompressible_ElasticQ94_Mixed_Formulation::make(int en, Global_Discretization& gd) {

    return new Incompressible_ElasticQ94_Mixed_Formulation(en,gd);

    }

    Incompressible_ElasticQ94_Mixed_Formulation::Incompressible_ElasticQ94_Mixed_Formulation

    (int en, Global_Discretization& gd) : Element_Formulation_Couple(en, gd) {

    Quadrature qp(2, 9);

    H1 Z(2, (double*)0, qp), Zai, Eta,N = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE( "int, int, Quadrature", 9, 2, qp);

    Zai &= Z[0]; Eta &= Z[1];

    N[0] = (1-Zai)*(1-Eta)/4; N[1] = (1+Zai)*(1-Eta)/4;

    N[2] = (1+Zai)*(1+Eta)/4; N[3] = (1-Zai)*(1+Eta)/4;

    N[8] = (1-Zai.pow(2))*(1-Eta.pow(2));

    N[0] -= N[8]/4; N[1] -= N[8]/4; N[2] -= N[8]/4; N[3] -= N[8]/4;

    N[4] = ((1-Zai.pow(2))*(1-Eta)-N[8])/2; N[5] = ((1-Eta.pow(2))*(1+Zai)-N[8])/2;

    N[6] = ((1-Zai.pow(2))*(1+Eta)-N[8])/2; N[7] = ((1-Eta.pow(2))*(1-Zai)-N[8])/2;

    N[0] -= (N[4]+N[7])/2; N[1] -= (N[4]+N[5])/2; N[2] -= (N[5]+N[6])/2; N[3] -= (N[6]+N[7])/2;

    C0 x = MATRIX("int, int, C0&, int, int", 9, 2, xl, 0, 0);

    H1 X = N*x; J dv(d(X).det());

    if(gd.type() == u_type) {

    H0 Nx = d(N) * d(X).inverse();

    double d_0[3][3] = { {2.0, 0.0, 0.0}, {0.0, 2.0, 0.0}, {0.0, 0.0, 1.0}};

    C0 D_0 = MATRIX("int, int, const double*", 3, 3, d_0[0]);

    double m_0[3] = {1.0, 1.0, 0.0}; C0 m = VECTOR("int, const double*", 3, m_0);

    H0 W_x = INTEGRABLE_SUBMATRIX("int, int, H0&", 1, nsd, Nx), Wx, Wy, B;

    Wx &= W_x[0][0]; Wy &= W_x[0][1];

    B &= (~Wx || C0(0.0) ) &

    (C0(0.0) || ~Wy ) &

    (~Wy || ~Wx );stiff &= ((~B) * (mu_*(D_0-2.0/3.0*(m%m)) * B)) | dv;

    } else if(gd.type() == p_type) {

    double sqrt3 = sqrt(3.0);

    H0 n = INTEGRABLE_VECTOR("int, Quadrature", 4/*nen*/, qp), zai, eta;

    zai &= ((H0)Z[0]); eta &= ((H0)Z[1]);

    n[0] = (1.0-sqrt3*zai)*(1.0-sqrt3*eta)/4.0; n[1] = (1.0+sqrt3*zai)*(1.0-sqrt3*eta)/4.0;

    n[2] = (1.0+sqrt3*zai)*(1.0+sqrt3*eta)/4.0; n[3] = (1.0-sqrt3*zai)*(1.0+sqrt3*eta)/4.0;

    stiff &= MATRIX("int, int", 13, 13);

    C0 stiff_sub = MATRIX("int, int, C0&, int, int", 4, 4, stiff, 9, 9);

    stiff_sub = -((n * (~n)) | dv)/K_;

    }}

    Advanced Finite Element MethodsChapter 5

    Element_Formulation_Couple* Incompressible_ElasticQ94_Mixed_Formulation::make(

  • 8/8/2019 Advanced Finite Element

    40/172

    490 Workbook of Applications in VectorSpace C++ Library

    int en, Global_Discretization_Couple& gdc) {

    return new Incompressible_ElasticQ94_Mixed_Formulation(en,gdc);

    }

    Incompressible_ElasticQ94_Mixed_Formulation::Incompressible_ElasticQ94_Mixed_Formulation

    (int en, Global_Discretization_Couple& gdc) : Element_Formulation_Couple(en, gdc) {Quadrature qp(2, 9);

    H1 Z(2, (double*)0, qp), Zai, Eta,

    N = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", 9, 2, qp);

    Zai &= Z[0]; Eta &= Z[1];

    N[0] = (1-Zai)*(1-Eta)/4; N[1] = (