Skip to main content

Handling Dirichlet Bounding Conditions in easifem (Part 1)

· 3 min read
Vikas Sharma
Assistant Professor, Kyoto University, Japan

Introduction

To apply boundary condition in FEM computation, EASIFEM, provides a class called DirichletBC_.

info

DirichletBC_ is a subclass of AbstractBC.

To understand how DirichletBC works, lets consider an example of linear elasticity. Let's say we want to apply the following boundary condition.

u=U0, on Γ\mathbf{u} = \mathbf{U}_{0}, \text{ on } \Gamma

We may think that there is only one boundary condition. But in easifem this is not the case. Actually, u\mathbf{u}, has three components in 3D (and two components in 2D). Therefore, the above boundary condition is actually boundary condition for uxu_x, uyu_y, and uzu_z. So, we have three boundary condition on a given boundary Γ\Gamma.

The second point, which is quite obvious, is that every boundary condition has two things:

  • The boundary
  • The value (condition)

To define the boundary EASIFEM employs the MeshSelection class. The value can be specified in several ways as mentioned below in this section.

note

Several instances of DirichletBC can have same boundary but different condition.

Mesh and degrees of freedom

Degree of freedom in mesh

Import from toml

We can initiate an instance of DirichletBC_ by importing the information from a toml-file. To do so, we will use the method called ImportFromToml.

Let us consider the following toml file

[domain]
filename = "./mesh/square_3x3.h5"
group = "/"
totalMedium = 1

[u]
name = "u"
engine = "NATIVE_SERIAL"
fieldType = "Normal"
spaceCompo = 1
timeCompo = 1
fedofName = "space"
geofedofName = "geofedof"

[u.geofedof]
baseContinuity = "H1"
baseInterpolation = "Lagrange"
ipType = "Equidistance"
baseType = "Monomial"

[u.space]
baseContinuity = "H1"
baseInterpolation = "Hierarchical"
# ipType = "Equidistance"
# baseType = "Monomial"
order = 4
scaleForQuadOrder = 2
quadOptName = "quadOpt"

[u.space.quadOpt]
isHomogeneous = true
quadratureType = "GaussLegendre"
# order = 2

[dbc]
name = "left_bottom_fix"
idof = 1
nodalValueType = "Constant"
value = 10.0
[dbc.boundary]
isSelectionByMeshID = true
[dbc.boundary.meshID]
line = [1, 4]

We use the following code to import the boundary condition from the above toml file.

!> author: Vikas Sharma, Ph. D.
! date: 2025-10-23
! summary: Study of DirichletBC class

PROGRAM main
USE GlobalData, ONLY: DFP, I4B, LGT
USE ExceptionHandler_Class, ONLY: e, EXCEPTION_INFORMATION
USE DirichletBC_Class
USE FEDomain_Class
USE AbstractMesh_Class
USE FEDOF_Class
USE ScalarField_Class
USE Display_Method
USE ReallocateUtility

IMPLICIT NONE

!----------------------------------------------------------------------------
! Parameters
!----------------------------------------------------------------------------
CHARACTER(*), PARAMETER :: tomlFileName = "./test1.toml"

!----------------------------------------------------------------------------
! Types and variables
!----------------------------------------------------------------------------
TYPE(DirichletBC_) :: obj
TYPE(FEDomain_) :: dom
TYPE(ScalarField_) :: u
TYPE(FEDOF_) :: fedof, geofedof
INTEGER(I4B) :: tsize, iNodeOnNode, iNodeOnEdge, iNodeOnFace, nrow, ncol

!----------------------------------------------------------------------------
! Allocatables and pointers
!----------------------------------------------------------------------------
CLASS(AbstractMesh_), POINTER :: cellMesh, boundaryMesh
INTEGER(I4B), ALLOCATABLE :: nodeNum(:)
REAL(DFP), ALLOCATABLE :: nodalValue(:, :)

!----------------------------------------------------------------------------
! Setting the verbosity
! In Debug mode, there will many messages printed to the screen
! Following code suppress information-exception.
!----------------------------------------------------------------------------

CALL e%setQuietMode(EXCEPTION_INFORMATION, .TRUE.)

!----------------------------------------------------------------------------
! Domain: Initiate FEDomain and print info
!----------------------------------------------------------------------------

CALL dom%ImportFromToml(tomlName="domain", filename=tomlFileName)
! CALL dom%DisplayDomainInfo(msg="DomainInfo: ")

!----------------------------------------------------------------------------
! ScalarField and FEDOF: Initiate scalarField and fedof
!----------------------------------------------------------------------------

CALL u%ImportFromToml(tomlName="u", fedof=fedof, geofedof=geofedof, dom=dom, &
filename=tomlFileName)
! CALL fedof%Display(msg="FEDOF info: ")

!----------------------------------------------------------------------------
! DirichletBC: Import from toml
!----------------------------------------------------------------------------

CALL obj%ImportFromToml(filename=tomlFileName, dom=dom, tomlName="dbc")
! CALL obj%Display("DirichletBC Info: ")

!----------------------------------------------------------------------------
! DirichletBC: Get the total node numbers
!----------------------------------------------------------------------------
tsize = obj%GetTotalNodeNum(fedof=fedof)
CALL Display(tsize, "Total Node Num: ")

!----------------------------------------------------------------------------
! DirichletBC: Get the node numbers
!----------------------------------------------------------------------------

CALL Reallocate(nodeNum, tsize, isExpand=.TRUE., expandFactor=2)
CALL obj%Get(fedof=fedof, nodeNum=nodeNum, tsize=tsize, &
iNodeOnNode=iNodeOnNode, iNodeOnEdge=iNodeOnEdge, &
iNodeOnFace=iNodeOnFace)
CALL Display(tsize, "tsize = ")
CALL Display(nodeNum(1:tsize), "nodeNum", full=.TRUE., orient="ROW")
CALL Display(iNodeOnNode, "iNodeOnNode = ")
CALL Display(iNodeOnFace, "iNodeOnFace = ")
CALL Display(iNodeOnEdge, "iNodeOnEdge = ")

!----------------------------------------------------------------------------
! DirichletBC: Get the nodal values
!----------------------------------------------------------------------------

CALL Reallocate(nodalValue, tsize, 2, isExpand=.TRUE., expandFactor=2)
CALL obj%Get(fedof=fedof, nodeNum=nodeNum, nodalValue=nodalValue, &
nrow=nrow, ncol=ncol)
CALL Display(nodalValue(1:nrow, 1:ncol), "nodalValue: ", &
full=.TRUE.)
CALL Display([nrow, ncol], "[nrow, ncol]: ")

!----------------------------------------------------------------------------
! Cleanup
!----------------------------------------------------------------------------
CALL dom%DEALLOCATE()
END PROGRAM main

We obtain the following information about the boundary condition.

PropertyValue
isInitTRUE
nameleft_bottom_fix
idof1
nodalValueTypeCONSTANT
isUserFunctionFALSE
isUseExternalFALSE
IsInitiatedTRUE
IsSelectionByMeshIDTRUE
IsSelectionByElemNumFALSE
IsSelectionByNodeNumFALSE
IsSelectionByBoxFALSE
MeshID PointFALSE
MeshID CurveTRUE
MeshID SurfaceFALSE
MeshID VolumeFALSE
ElemNum PointFALSE
ElemNum CurveFALSE
ElemNum SurfaceFALSE
ElemNum VolumeFALSE
NodeNum PointFALSE
NodeNum CurveFALSE
NodeNum SurfaceFALSE
NodeNum VolumeFALSE
Box PointFALSE
Box CurveFALSE
Box SurfaceFALSE
Box VolumeFALSE

Getting Total Node Numbers

To get the total number of nodes where the boundary condition is applied, we can use the method called GetTotalNodeNum.

CALL Display(obj%GetTotalNodeNum(fedof=fedof), "Total Node Num: ")
Results

Total Node Num: 18

There is a total of 18 nodes where the boundary condition is applied. Actually, node number 1 is counted two times because it is common to bottom and left boundaries.

Getting Node Numbers

To get the node numbers we call Get method. These node numbers are degrees of freedom numbers for FEDOF. You can use these indices to set and get the values in node fields.

CALL obj%Get(fedof=fedof, nodeNum=nodeNum, tsize=tsize, &
iNodeOnNode=iNodeOnNode, iNodeOnEdge=iNodeOnEdge, &
iNodeOnFace=iNodeOnFace)
CALL Display(tsize, "tsize = ")
CALL Display(nodeNum(1:tsize), "nodeNum", full=.TRUE., orient="ROW")
CALL Display(iNodeOnNode, "iNodeOnNode = ")
CALL Display(iNodeOnFace, "iNodeOnFace = ")
CALL Display(iNodeOnEdge, "iNodeOnEdge = ")
Results
                                nodeNum
----------------------------------------------------------------------
1 5 2 4 8 1 10 11 12 31 32 33 28 29 30 19 20 21

iNodeOnNode = 1
iNodeOnFace = 7
iNodeOnEdge = 19
  • Node number 1 to 6 (7-1) are vertex dof numbers.
  • Node number 7 to 18 (19-1) are face dof numbers
  • Node number 19 to 18 are edge dof numbers (There are no edges)