question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Implementing Conforming CR #437

See original GitHub issue

Hi @kinnala,

I finally got back to implementing conforming CR (see 3.2.3 in here for a concise definition of the spaces for velocity and pressure) using the suggestions in #437 for incompressible stokes (hyperelasticity). Since I plan to use this element in my work, and if you deem it fit then include it in scikit-fem. This is what I have for the definitions so far…

3D

class ElementTetCCR(ElementH1):

    nodal_dofs = 1
    facet_dofs = 1
    edge_dofs = 1
    interior_dofs = 1
    maxdeg = 4
    dofnames = ["u", "u", "u", "u"]
    doflocs = np.array(
        [
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 0.0],
            [0.0, 0.0, 1.0],
            [0.5, 0.5, 0.0],
            [0.0, 0.5, 0.0],
            [0.5, 0.0, 0.0],
            [0.5, 0.0, 0.5],
            [0.0, 0.5, 0.5],
            [0.0, 0.0, 0.5],
            [1.0 / 3, 1.0 / 3, 0.0],
            [1.0 / 3, 1.0 / 3, 1.0 / 3],
            [0.0, 1.0 / 3, 1.0 / 3],
            [1.0 / 3, 0.0, 1.0 / 3],
            [1.0 / 4, 1.0 / 4, 1.0 / 4],
        ]
    )
    refdom = RefTet

    def lbasis(self, X, i):
        x, y, z = X 

        if i == 0:  # at (1,0,0)
            phi = 3 * x * (y * z + (y + z) * (-x - y - z + 1)) + x * (
                2 * x - 4 * y * z * (-x - y - z + 1) - 1
            )
            dphi = np.array(
                [
                    -3*x*(y + z) + 2*x*(2*y*z + 1) + 2*x + 4*y*z*(x + y + z - 1) + 3*y*z - 3*(y + z)*(x + y + z - 1) - 1,
                    x*(4*z - 3)*(x + 2*y + z - 1),
                    x*(4*y - 3)*(x + y + 2*z - 1),
                ]
            )
        elif i == 1:  # at (1,0,0)
            phi = y*(4*x*z*(x + y + z - 1) + 3*x*z + 2*y - 3*(x + z)*(x + y + z - 1) - 1)
            dphi = np.array(
                [
                    y*(4*z - 3)*(2*x + y + z - 1),
                    4*x*z*(x + y + z - 1) + 3*x*z - 3*y*(x + z) + 2*y*(2*x*z + 1) + 2*y - 3*(x + z)*(x + y + z - 1) - 1,
                    y*(4*x - 3)*(x + y + 2*z - 1),
                ]
            )
        elif i == 2:  # at (0,1,0)
            phi = (x + y + z - 1)*(4*x*y*z - 3*x*y - 3*x*z + 2*x - 3*y*z + 2*y + 2*z - 1)
            dphi = np.array(
                [
                    8*x*y*z - 6*x*y - 6*x*z + 4*x + 4*y**2*z - 3*y**2 + 4*y*z**2 - 13*y*z + 7*y - 3*z**2 + 7*z - 3,
                    4*x**2*z - 3*x**2 + 8*x*y*z - 6*x*y + 4*x*z**2 - 13*x*z + 7*x - 6*y*z + 4*y - 3*z**2 + 7*z - 3,
                    4*x**2*y - 3*x**2 + 4*x*y**2 + 8*x*y*z - 13*x*y - 6*x*z + 7*x - 3*y**2 - 6*y*z + 7*y + 4*z - 3,
                ]
            )
        elif i == 3:  # at (0,0,1)
            phi = z*(4*x*y*(x + y + z - 1) + 3*x*y + 2*z - 3*(x + y)*(x + y + z - 1) - 1)
            dphi = np.array(
                [
                    z*(4*y - 3)*(2*x + y + z - 1),
                    z*(4*x - 3)*(x + 2*y + z - 1),
                    4*x*y*(x + y + z - 1) + 3*x*y - 3*z*(x + y) + 2*z*(2*x*y + 1) + 2*z - 3*(x + y)*(x + y + z - 1) - 1,
                ]
            )
        elif i == 4:  # between (0,1)
            phi = 4*x*y*(3*x + 3*y - 8*z*(x + y + z - 1) - 2)
            dphi = np.array(
                [
                    4*y*(-x*(8*z - 3) + 3*x + 3*y - 8*z*(x + y + z - 1) - 2),
                    4*x*(3*x - y*(8*z - 3) + 3*y - 8*z*(x + y + z - 1) - 2),
                    32*x*y*(-x - y - 2*z + 1),
                ]
            )
        elif i == 5:  # between (1,2)
            phi = -4*y*(x + y + z - 1)*(8*x*z - 3*x - 3*z + 1)
            dphi = np.array(
                [
                    4*y*(-8*x*z + 3*x + 3*z - (8*z - 3)*(x + y + z - 1) - 1),
                    4*(-x - 2*y - z + 1)*(8*x*z - 3*x - 3*z + 1),
                    4*y*(-8*x*z + 3*x + 3*z - (8*x - 3)*(x + y + z - 1) - 1),
                ]
            )
        elif i == 6:  # between (0,2)
            phi = -4*x*(x + y + z - 1)*(8*y*z - 3*y - 3*z + 1)
            dphi = np.array(
                [
                    4*(-2*x - y - z + 1)*(8*y*z - 3*y - 3*z + 1),
                    4*x*(-8*y*z + 3*y + 3*z - (8*z - 3)*(x + y + z - 1) - 1),
                    4*x*(-8*y*z + 3*y + 3*z - (8*y - 3)*(x + y + z - 1) - 1),
                ]
            )
        elif i == 7:  # between (0,3)
            phi = 4*x*z*(3*x - 8*y*(x + y + z - 1) + 3*z - 2)
            dphi = np.array(
                [
                    4*z*(-x*(8*y - 3) + 3*x - 8*y*(x + y + z - 1) + 3*z - 2),
                    32*x*z*(-x - 2*y - z + 1),
                    4*x*(3*x - 8*y*(x + y + z - 1) - z*(8*y - 3) + 3*z - 2),
                ]
            )
        elif i == 8:
            phi = -4*y*z*(8*x*(x + y + z - 1) - 3*y - 3*z + 2)
            dphi = np.array(
                [
                    32*y*z*(-2*x - y - z + 1),
                    4*z*(-8*x*(x + y + z - 1) - y*(8*x - 3) + 3*y + 3*z - 2),
                    4*y*(-8*x*(x + y + z - 1) + 3*y - z*(8*x - 3) + 3*z - 2),
                ]
            )
        elif i == 9:
            phi = -4*z*(x + y + z - 1)*(8*x*y - 3*x - 3*y + 1)
            dphi = np.array(
                [
                    4*z*(-8*x*y + 3*x + 3*y - (8*y - 3)*(x + y + z - 1) - 1),
                    4*z*(-8*x*y + 3*x + 3*y - (8*x - 3)*(x + y + z - 1) - 1),
                    4*(-x - y - 2*z + 1)*(8*x*y - 3*x - 3*y + 1),
                ]
            )
        elif i == 10:
            phi = 27*x*y*(4*z - 1)*(x + y + z - 1)
            dphi = np.array(
                [
                   27*y*(4*z - 1)*(2*x + y + z - 1),
                   27*x*(4*z - 1)*(x + 2*y + z - 1),
                   27*x*y*(4*x + 4*y + 8*z - 5)
                ]
            )
        elif i == 11:
            phi = 27*x*y*z*(4*x + 4*y + 4*z - 3)
            dphi = np.array(
                [
                    27*y*z*(8*x + 4*y + 4*z - 3),
                    27*x*z*(4*x + 8*y + 4*z - 3),
                    27*x*y*(4*x + 4*y + 8*z - 3)
                ]
            )
        elif i == 12:
            phi = 27*y*z*(4*x - 1)*(x + y + z - 1)
            dphi = np.array(
                [
                  27*y*z*(8*x + 4*y + 4*z - 5),
                  27*z*(4*x - 1)*(x + 2*y + z - 1),
                  27*y*(4*x - 1)*(x + y + 2*z - 1)
                ]
            )
        elif i == 13:
            phi = 27*x*z*(4*y - 1)*(x + y + z - 1)
            dphi = np.array(
                [
                    27*z*(4*y - 1)*(2*x + y + z - 1),
                    27*x*z*(4*x + 8*y + 4*z - 5),
                    27*x*(4*y - 1)*(x + y + 2*z - 1)
                ]
            )
        elif i == 14:
            phi = 256*x*y*z*(-x - y - z + 1)
            dphi = np.array(
                [
                   256*y*z*(-2*x - y - z + 1),
                   256*x*z*(-x - 2*y - z + 1),
                   256*x*y*(-x - y - 2*z + 1)                
                ]
            )
        else:
            self._index_error()

        return phi, dphi

2D

class ElementTriCCR(ElementH1):

    nodal_dofs = 1
    facet_dofs = 1
    interior_dofs = 1
    maxdeg = 3
    dofnames = ['u', 'u', 'u']
    doflocs = np.array([[1., 0.],
                        [0., 1.],
                        [0., 0.],
                        [0.5, 0.5],
                        [0, 0.5],
                        [0.5, 0.],
                        [1./3, 1./3]])
    refdom = RefTri

    def lbasis(self, X, i):
        x, y = X

        if i == 0: 
            phi = -x*(-2*x + 3*y*(x + y - 1) + 1)
            dphi = np.array([6*x*y + 4*x + 3*y**2 - 3*y - 1,
                             3*x*(x + 2*y - 1)])
        elif i == 1:
            phi = -y*(3*x*(x + y - 1) - 2*y + 1)
            dphi = np.array([3*y*(-2*x - y + 1),
                             -3*x**2 - 6*x*y + 3*x + 4*y - 1])
        elif i == 2:
            phi = -(-2*x + y*(3*x - 2) + 1)*(x + y - 1)
            dphi = np.array([-6*x*y + 4*x - 3*y**2 + 7*y - 3,
                             -3*x**2 - 6*x*y + 7*x + 4*y - 3])
        elif i == 3:  # 0->1
            phi = 4*x*y*(3*x + 3*y - 2)
            dphi = np.array([4*y*(6*x + 3*y - 2),
                             4*x*(3*x + 6*y - 2)])
        elif i == 4:  # 1->2
            phi = 4*y*(3*x - 1)*(x + y - 1)
            dphi = np.array([4*y*(6*x + 3*y - 4),
                             4*(3*x - 1)*(x + 2*y - 1)])
        elif i == 5:  # 0->2
            phi = 4*x*(3*y - 1)*(x + y - 1)
            dphi = np.array([4*(3*y - 1)*(2*x + y - 1),
                             4*x*(3*x + 6*y - 4)])
        elif i == 6:
            phi = 27*x*y*(-x - y + 1)
            dphi = np.array(
                [
                    27*y*(-2*x - y + 1),
                    27*x*(-x - 2*y + 1)
                ]
            )
        else:
            self._index_error()

        return phi, dphi

I am looking to first test this in example 36 (in doing so I realized that example 36 was written in a non-standard fashion – I plan to clean that up soon as well). Since the pressure space is discontinuous P1, and now that you have ElementTetDG and ElementTriDG already in scikit-fem, it seems that example 36 should be reproducible by simply changing the relevant spaces to

uelem = ElementVectorH1(ElementTetCCR())
pelem = ElementTetDG(ElementTetP1())

Please let me know what you think. In the meanwhile, I will check if I have implemented everything correctly (basis functions and their gradients)

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (9 by maintainers)

github_iconTop GitHub Comments

2reactions
kinnalacommented, Jun 15, 2021

Here are some tests that are run against the elements (if applicable):

We also test the convergence rates, e.g.: https://github.com/kinnala/scikit-fem/blob/master/tests/test_convergence.py#L213

A new file is created: skfem/element/element_tri/element_tri_ccr.py and imports added to skfem/element/element_tri/__init__.py and skfem/element/__init__.py so that wildcard works properly. Then the above tests are modified accordingly.

If you want you can open a pull request with these changes.

0reactions
kinnalacommented, Jun 20, 2021

Merged

Read more comments on GitHub >

github_iconTop Results From Across the Web

Pub 100-04 Medicare Claims Processing - CMS Manual System
Background: This instruction revises Section 30, Chapter 6 to include ICD-9-CM coding guidance for Skilled Nursing Facilities (SNFs) and removes Home Health ...
Read more >
Proposed rule: Money Market Fund Reforms - SEC.gov
The proposal would amend certain reporting requirements on Forms N-MFP and N-CR to improve the availability of information about money market ...
Read more >
FEDERAL MOTOR VEHICLE SAFETY STANDARDS - GovInfo
No standard applies to a vehicle or item of equipment manufactured for, and sold directly to, the Armed Forces of the United States...
Read more >
A Resource Guide to the U.S. Foreign Corrupt Practices Act
This guide is intended to provide information for businesses and individuals regarding the U.S. Foreign Corrupt Practices. Act (FCPA). The guide has been ......
Read more >
All Business Courses: SUNY Brockport
This course covers a broad range of topics, including consumer culture, online communities, self-presentation and branding, business and marketing, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found