Exploring MFEM

mfem c++ fem library

With little time I have after office and playing with kids , I am devoting some to this MFEM library.

Really good piece of software. Exploration continues.

So What is MFEM?

No, it’s not Ministry of Finance and Economics Management, it’s …….

MFEM is a lightweight, general, scalable C++ library for finite element methods and available at http://mfem.googlecode.com

The goal of MFEM is to enable research and development of scalable
finite element discretization and solver algorithms through general
finite element abstractions, accurate and flexible visualization, and
tight integration with the hypre linear solvers library. Its features
include:
– 2D and 3D, arbitrary high-order H1, H(curl), H(div), L2 and NURBS
elements.
– Parallel version scalable to hundreds of thousands of MPI cores.
– Conforming or nonconforming adaptive mesh refinement (AMR),
including anisotropic refinement.
– Galerkin, mixed, isogeometric, DG and DPG discretizations.
– Support for triangular, quadrilateral, tetrahedral and hexahedral
elements with curved boundaries.
– Lightweight interactive OpenGL visualization with GLVis,
http://glvis.googlecode.com.

An interactive documentation of MFEM’s serial and parallel example
codes can be found here
MFEM is freely available under LGPL 2.1.

 

Foundation of FEM

Spring_FEM_in_Python
“Spring is the foundation of FEM. Understand this well and you are through in this course.” said the IISC professor as we settled on the hard benches on the first day of our 6 month FEM course at IISC, bangalore.

The course proved very useful. Learnt a lot. Fortunately , being in NAL had access to matlab and so converted the learning into matlab scripts. Today those scripts must be lying in some system in NAL.

Two months back, working on a problem in office, revisited all those notes and had this impulse to revisit the spring FEM problem in python…

So here’s the result. Two problem defined and solved in python.


"""
Created on Tue April 06 18:46:01 2014

@author: Sukhbinder Singh

Finite Element Analysis of spring system

problem 1

               #---^^^^^----#
#              #
#-----^^^^^----# ===> P
#              #
               #---^^^^^----#

1              2            3,4     

Spring Problem

P=100
ki=10
u1=u3=u4 =0


problem 2

#                             #
#------^^^^^^^^^^^^^^^^-------#
#                             #
#         |---^^^^--|         #
#---^^^^--|==>P     |--^^^^---#
#         |---^^^^--|         #
          |                   #
          |------^^^^^^-------#

1         2         3         4

k1=10,k2=15,k3=20,k4=25,k5=30,k6=35
P=100
u1=u4=0


Solution for problem 1
Displacement
0 0.0
1 3.33333333333
2 0.0
3 0.0

Reactions
0 -33.3333333333
2 -33.3333333333
3 -33.3333333333


Solution for problem 2
Displacement
0 0.0
1 1.54589371981
2 0.869565217391
3 0.0

Reactions
0 -23.1884057971
3 -76.8115942029


#usage of np.ix_
import numpy as np
A = np.array([ 1, 2, 3, 4, 4,
      2, 3, 4, 5, 3,
      4, 5, 6, 7, 2,
      5, 6, 7, 8, 9,
      6, 7, 8, 9, 0 ]).reshape(5, 5)

B = np.array([60, 70, 80, 90]).reshape(2, 2)
A[np.ix_([2, 4], [2, 4])] = B  


# usage of np.setdiff1d(ar1,ar2)
# Return the sorted, unique values in `ar1` that are not in `ar2`.
a = np.array([1, 2, 3, 2, 4, 1])
b = np.array([3, 4, 5, 6])
np.setdiff1d(a, b)

"""
import numpy as np

p1 = True # True for problem 1

if p1: # problem 1
    elemNodes= np.array([[0,1],[1,2],[1,3]])
    numElem = elemNodes.shape[0]
    numNodes=4
    presDof=np.array([0,2,3])
    k=np.array([10,10,10]) # Spring Stiffness
else: # problem 2
    elemNodes= np.array([[0,3],[0,1],[1,2],[1,2],[1,3],[2,3]])
    numElem = elemNodes.shape[0]
    numNodes=4
    presDof=np.array([0,3])
    k=np.array([10,15,20,25,30,35]) # Spring Stiffness

disp=np.zeros((numNodes,1))
force=np.zeros((numNodes,1))
stiffness=np.zeros((numNodes,numNodes))

force[1]=100.0

for e in xrange(numElem):
    stiffness[np.ix_(elemNodes[e,:],elemNodes[e,:])]+=np.array([[k[e],-k[e]],[-k[e],k[e]]])

actDof=np.setdiff1d(np.arange(numNodes),presDof)

disp1=np.linalg.solve(stiffness[np.ix_(actDof,actDof)],force[np.ix_(actDof)]);
disp[np.ix_(actDof)]=disp1

print "\nDisplacement"
for i,d in enumerate(disp):
    print i,d[0]

# reactions
react = np.dot(stiffness,disp)
reaction = react[presDof]

print "\nReactions"
for (p,r) in zip(presDof,reaction):
    print p,r[0]


Brief Intro to FEA or Finite Element Method (FEM)

introduction-to-fem-short-introduction
Recently someone asked me for a simple and short primer or refresher material on Finite element Method.

Here’s a super simple, brief, to the point , no nonsense PDF on FEA theory from the university of victoria.

Brief and simple. Just enough material to spark interest for the curious!!!

Brief Intro to FEA or Finite Element Method (FEM) [PDF]

Do you know any such good, brief and useful resource? Please share.

Unofficial History of ANSYS

ansys A few days back I was searching for a paper and stumbled upon this interesting page. The page listed an interesting account of unofficial history of ANSYS. I don’t know why, but i like reading accounts like this, so here’s part of it that i liked…

In 1963, Dr. John Swanson worked at Westinghouse Astronuclear Labs in Pittsburgh, responsible for stress analysis of the components in NERVA nuclear reactor rockets. He used computer codes to model and predict transient stresses and displacements of the reactor system due to thermal and pressure loads.

Swanson continued to develop 3-D analysis, plate bending, nonlinear analysis for plasticity and creep, and transient dynamic analysis, in the next several years, using a finite element heat conduction program that was developed by Wilson at Aerojet. The old Westinghouse codes included a 2d/axisymmetric one also, possibly called FEATS (according to Kohnke).

John wanted to combine these codes to remove the duplication, like equation solvers and some postprocessing Swanson believed an integrated, general-purpose FEA code could be used to do complex calculations that engineers typically did manually, such as heat transfer analysis. It would save money and time for Westinghouse and other companies.

Westinghouse didn’t support the idea, and Swanson left the company in 1969. Before he left, he made sure that all code work had been sent to COSMIC, so that he could pick it up again from the outside.

Swanson Analysis Systems, Inc was incorporated in the middle of 1970 at Swanson’s home. The offices were part of Swanson’s home (There was no garage) in Pittsburgh. at the same time, Westinghouse realized that they needed John, so they hired him as a consultant. John said sure, but with the proviso that whatever he put into STASYS, the Westinghouse code, he could also put into ANSYS. Westinghouse had no trouble with this, as they just wanted to solve their problems. So this consulting kept bread on the table for the Swansons, and at the same time brought forth further improvements to ANSYS.

He developed his program using a keypunch and a time-shared mainframe at U.S. Steel. The first version of ANSYS was coded by the end of 1970, and the ANSYS program was first leased soon after that. Westinghouse was the first customer, running as a data center. The data center was at the Telecommunications Center on the Parkway East, on the east side of  Pittsburgh.

According to Dr. Swanson, the name ANSYS was because the copyright lawyers assured Swanson that ANSYS was just a name, and did not stand for anything. Understandable, during that period all programs were "written" on punch card. When installing the program on the customer’s computer, it meant carried a relatively big case of punch cards to the customer’s place, and fed them into the machine.

Dr. Peter Kohnke met John Swanson first about early 1971. Swanson offered Peter a job in the fall of 71, but Peter did not accept. As that time Peter was a brand new father at the time, and Westinghouse looked a lot more secure than SAS. Peter told John he was interested and would accept in the spring of 72, but then he had hired Gabe DeSalvo, and did not have the resources to hire Peter also. But that fall John did, and then hired Peter. Dr. Peter Kohnke’s start date was 1/1/73. (Dr. Kohnke still worked at ANSYS as of December of2005).

When Peter started work, he asked what John wanted him to do. John told Peter that he developed code, did technical support, wrote manuals, gave seminars and did systems work so that the program would run on a variety of systems. John said he needed relief, so Peter should pick one or two of them. Ultimately, Peter did all of them, except systems work.

In around 1970, users can ran ANSYS 2.x on a CDC 6600 machine over the Cybernet timesharing network. That time only fixed format input was available. The users would work up the input listing off-line, key it onto a tape cassette, log on, submit the run about quitting time for the best computer rates and stop by the CDC data center next morning to find out what went wrong. In 1973, ANSYS ran on three kinds of hardware: CDC, Univac, and IBM. And around 1973 the USS mainframe that they used to develop code was the US Steel CDC 6500.

The first minicomputer that ANSYS ran on was a MODCOMP 4 (or IV?) VAX came later. Being a small company, everyone did everything. When a ‘mini’ computer was delivered, everyone helped wrestle it off of the truck. When printout paper was delivered, everyone helped unload the
boxes.

Lot more to read at Unofficial history of ANSYS

Plate Mesh File

A few months back, i needed a plate model. Searched the net and tried creating it with a CAD software, but then said to myself. What the heck!! All I need is a mesh with quad elements and so wrote this program.

Not a polished code, but if you need a patran neurtal mesh file  for a simple plate with custom amount of 4 noded elements, then this is the program for you. Run this and import the generated file any CAD/CAE program.

 

        IMPLICIT NONE
        INTEGER N_elts_x,D_Node_Number,i,j,N_elts_y
        REAL*8 coord(121,2),dx,dy,PlateLength,PlateHeight
        INTEGER conec(100,4),nnodes,nele,ishap,D_Node_Numbery,ielem

        CHARACTER(len=80) title,datetime
        DATA title/"Created by fortran code"/
        DATA datetime/" Developed by sukhbinder"/



        PlateLength = 0.25
        PlateHeight = 0.25
! number of elements in x dir
        N_elts_x = 3
! number of elements in y dir
        N_elts_y = 4


        dx = PlateLength / DBLE(N_elts_x)
        dy = PlateHeight / DBLE(N_elts_y)

        D_Node_Number = N_elts_x + 1
        D_Node_Numbery = N_elts_y + 1
        DO i = 1 ,(N_elts_y + 1)
          DO j =1 , (N_elts_x + 1)
            COORD((i-1)*D_Node_Number+j , 1 ) = (j-1) *  dx
            COORD((i-1)*D_Node_Number+j , 2 ) = (i-1) * dy
          END DO
        END DO
!
          ielem=0
          DO j = 1, N_elts_y
            DO i = 1, N_elts_x

              ielem = ielem + 1

              conec(ielem,1) = ( j - 1 ) * ( N_elts_x + 1 ) + i
              conec(ielem,2) = ( j - 1 ) * ( N_elts_x + 1 ) + i + 1
              conec(ielem,3) =   j       * ( N_elts_x + 1 ) + i + 1
              conec(ielem,4) =   j       * ( N_elts_x + 1 ) + i


            END DO
          END DO

        DO i=1,121
          WRITE(*,'(i,2f12.8)') i,coord(i,:)
        END DO

        DO i=1,100
        WRITE(*,'(5i)') i,conec(i,:)
        END DO

!  Writing the file

        nnodes=(N_elts_x+1)*(N_elts_y+1)
        nele=N_elts_x*N_elts_y
        ishap =4

        OPEN(13,file="c:\temp\temp.mesh")

        WRITE(13,9000) 25,0,0,1,0,0,0,0,0
        WRITE(13,'(A)') title
        WRITE(13,9000) 26,0,0,1,nnodes,nele,0,0,0
        WRITE(13,'(A)') datetime

        DO i=1, nnodes
           WRITE(13,9005) i,0,2,0,0,0,0,0,coord(i,1),coord(i,2),0.0d0
        END DO

        DO i=1,nele
           WRITE(13,9010) i, ishap, ishap+1,0,0,0,0,0, ishap, 1,1,0,0.d0,0.d0,0.d0,conec(i,1:ishap)
        END DO
        WRITE(13,9000) 99, 0, 0, 1, 0, 0, 0, 0, 0



9000    format(i2, 8i8)
9005    format( ' 1', 8i8,  /&
           1p,3e16.9 / &
             '1G       6       0       0  000000')
9010  format( ' 2', 8i8, / &
                   4I8,3e16.9 /&
                 (10i8 ))
        CLOSE(13)
        END