IvyFEM.dll, a finite element method library for .NET, is under development. It is a library that is supposed to be used in C #, but I found that it could be used from Python, so I will write it as an article.
I decided to use Python.NET. http://pythonnet.github.io/
Below, it is assumed that Python is already installed in the Windows environment.
Execute the following from the command prompt.
py -m pip install pythonnet
Download the latest package from the IvyFEM page on Github and extract it to your working directory (see How to install the IvyFEM page, VC ++ runtime required). IvyFEM: https://github.com/ryujimiya/IvyFEM/
When expanded, it will be as follows.
I tried to solve Poisson's equation in Python.
It takes a square area and imposes a boundary condition with zero potential on the sides. A circular region is taken inside the region, and the potential distribution of the entire region when a charge is applied to that region is calculated.
main2.py
import clr
clr.AddReference("System")
from System import UInt32
clr.AddReference("System.Collections")
from System.Collections.Generic import List, IList
clr.AddReference('IvyFEM')
from IvyFEM \
import \
Cad2D, Mesher2D, FEWorld, \
FiniteElementType, \
PoissonMaterial, \
CadElementType, FieldValueType, FieldFixedCad, \
Poisson2DFEM
clr.AddReference('IvyFEM')
from IvyFEM.Linear \
import \
LapackEquationSolver, LapackEquationSolverMethod, \
IvyFEMEquationSolver, IvyFEMEquationSolverMethod
clr.AddReference('OpenTK')
from OpenTK import Vector2d
cad = Cad2D()
pts = List[Vector2d]()
pts.Add(Vector2d(0.0, 0.0))
pts.Add(Vector2d(1.0, 0.0))
pts.Add(Vector2d(1.0, 1.0))
pts.Add(Vector2d(0.0, 1.0))
lId1 = cad.AddPolygon(pts).AddLId
print("lId1 = " + str(lId1))
#Source
lId2 = cad.AddCircle(Vector2d(0.5, 0.5), 0.1, lId1).AddLId
print("lId2 = " + str(lId2))
eLen = 0.05
mesher = Mesher2D(cad, eLen)
#See coordinates
vecs = mesher.GetVectors()
cnt = len(vecs)
print("len(vecs) = " + str(cnt))
coId = 0
for vec in vecs:
print("vec[" + str(coId) + "] " + str(vec.X) + ", " + str(vec.Y))
coId += 1
world = FEWorld()
world.Mesh = mesher
dof = 1 #scalar
feOrder = 1
quantityId = world.AddQuantity(dof, feOrder, FiniteElementType.ScalarLagrange)
world.ClearMaterial()
ma1 = PoissonMaterial()
ma1.Alpha = 1.0
ma1.F = 0.0
ma2 = PoissonMaterial()
ma2.Alpha = 1.0
ma2.F = 100.0
maId1 = world.AddMaterial(ma1)
maId2 = world.AddMaterial(ma2)
lId1 = 1
world.SetCadLoopMaterial(lId1, maId1)
lId2 = 2
world.SetCadLoopMaterial(lId2, maId2)
zeroEIds = [1, 2, 3, 4]
zeroFixedCads = List[FieldFixedCad]()
for eId in zeroEIds:
#scalar
#Note that it is an overload
fixedCad = FieldFixedCad.Overloads[UInt32, CadElementType, FieldValueType](eId,CadElementType.Edge,FieldValueType.Scalar)
zeroFixedCads.Add(fixedCad)
world.SetZeroFieldFixedCads(quantityId, zeroFixedCads)
#DEBUG
zeroFixedCads = world.GetZeroFieldFixedCads(quantityId)
print("len(zeroFixedCads) = " + str(len(zeroFixedCads)))
world.MakeElements()
feIds = world.GetTriangleFEIds(quantityId)
feCnt = len(feIds)
print("feCnt = " + str(feCnt))
for feId in feIds:
print("--------------")
print("feId = " + str(feId))
triFE = world.GetTriangleFE(quantityId, feId)
nodeCoIds = triFE.NodeCoordIds
elemNodeCnt = nodeCoIds.Length
for iNode in range(elemNodeCnt):
print("coId[" + str(iNode) + "] = " + str(nodeCoIds[iNode]))
#Poisson equation FEM
FEM = Poisson2DFEM(world)
#Linear solver
'''
solver = LapackEquationSolver()
solver.IsOrderingToBandMatrix = True
solver.Method = LapackEquationSolverMethod.Band
FEM.Solver = solver
'''
solver = IvyFEMEquationSolver()
solver.Method = IvyFEMEquationSolverMethod.NoPreconCG
FEM.Solver = solver
#solve
FEM.Solve()
U = FEM.U
#result
nodeCnt = len(U)
for nodeId in range(nodeCnt):
print("-------------")
coId = world.Node2Coord(quantityId, nodeId)
value = U[nodeId]
print(str(nodeId) + " " + str(coId) + " " + "{0:e}".format(value))
py -m main2
I solved Poisson's equation from Python using IvyFEM.dll.
Recommended Posts