// —————————-
// Groups and Regions
// —————————-
Group {
Region[1] = Region[Physical Surface(“MaterialRegion1”)]; // Upper circle
Region[2] = Region[Physical Surface(“MaterialRegion2”)]; // Lower circle
Region[3] = Region[Physical Surface(“RectangleRegion”)]; // Rectangle (air)
Boundary[1] = Region[Physical Line(“Bottomedge”)]; // Bottom edge
Boundary[3] = Region[Physical Line(“Topedge”)]; // Top edge
}
// —————————-
// Material Properties
// —————————-
Function {
MuSoft[] = 1e-2; // Soft magnetic material permeability
MuAir[] = 4 * Pi * 1e-7; // Air permeability
PhiBoundary1[] = 0; // Scalar potential at Bottomedge
PhiBoundary3[] = 1; // Scalar potential at Topedge
}
// —————————-
// Function Spaces
// —————————-
FunctionSpace {
{ Name H1 ; // Define the H1 space
Type Form0 ; // Scalar field
BasisFunction {
{ Name sn ; NameOfCoef nodal ; Function BF_Node ; }
}
Constraint {
{ NameOfConstraint BoundaryConditions ; }
}
}
}
// —————————-
// Formulation
// —————————-
Formulation {
{ Name MagneticScalarFormulation ;
Type FemEquation ;
Quantity {
{ Name MagneticScalarPotential ; Type Local ; NameOfSpace H1 ; }
}
Equation {
// Weak form of the scalar magnetic potential equation
Galerkin { [ 1/MuSoft[] * Dof{MagneticScalarPotential}, {MagneticScalarPotential} ]; In Region[1, 2]; }
Galerkin { [ 1/MuAir[] * Dof{MagneticScalarPotential}, {MagneticScalarPotential} ]; In Region[3]; }
}
}
}
// —————————-
// Boundary Conditions
// —————————-
Constraint {
{ Name BoundaryConditions ;
Type Assign ;
Case {
{ Region Boundary[1]; Value PhiBoundary1[]; } // Bottom edge
{ Region Boundary[3]; Value PhiBoundary3[]; } // Top edge
}
}
}
// —————————-
// Resolution
// —————————-
Resolution {
{ Name MagneticScalarResolution ;
System {
{ NameOfFormulation MagneticScalarFormulation ; }
}
Operation {
Generate[] ;
Solve[] ;
SaveSolution[MagneticScalarPotential] ;
}
}
}
// —————————-
// Post-Processing
// —————————-
PostProcessing {
{ Name MagneticScalarField ;
Quantity {
{ Name MagneticScalarPotential ; Value { Local { [ {MagneticScalarPotential} ]; In Region[1, 2, 3]; }}}
}
}
}
—————————- —————————- —————————-
Esys
Docker のインストール 省略
Docker コンテナ作成
docker run -it -d –name esysparticle-container ubuntu
必要な依存関係のインストール
apt update
apt upgrade
apt install -y build-essential cmake git python3 python3-pip wget
apt install libtool automake build-essential bzr cmake mpi-default-bin mpi-default-dev libboost-all-dev python-is-python3
ソースコードの取得
dionの親切に乗りたかったがNG
https://launchpad.net/esys-particle/trunk/2.3/+download
mkdir -p ESyS-Particle
cd ESyS-Particle
bzr branch lp:esys-particle esys-particle-trunk
cd esys-particle-trunk
直DL
wget https://launchpad.net/esys-particle/+download#:~:text=esys%2Dparticle%2D3.0%2Dalpha.tar.gz –no-check-certificate
アーカイブを展開
tar -xvzf esys-particle-2.3.tar.gz
cd esys-particle-2.3
MPI-3.0 以降では削除された関数が含まれているため対応
export OMPI_MCA_mpi_compatibility=true
apt remove –purge mpi-default-bin mpi-default-dev
apt install openmpi-bin=1.10.7-1build1 openmpi-common=1.10.7-1build1 libopenmpi-dev=1.10.7-1build1
ビルド
mkdir build
cd build
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
cmake ..
make -j$(nproc)
make install
環境変数
export PATH=/usr/local/bin:$PATH
export LIBRARY_PATH=/usr/local/lib:$LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
export PYTHONPATH=/usr/local/lib/python3/dist-packages:$PYTHONPATH
永続化
echo ‘export PATH=/usr/local/bin:$PATH’ >> ~/.bashrc
echo ‘export LIBRARY_PATH=/usr/local/lib:$LIBRARY_PATH’ >> ~/.bashrc
echo ‘export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH’ >> ~/.bashrc
echo ‘export PYTHONPATH=/usr/local/lib/python3/dist-packages:$PYTHONPATH’ >> ~/.bashrc
source ~/.bashrc
sudo apt update
sudo apt install –reinstall ca-certificates
sudo update-ca-certificates
ビルドとインストール
MPI-3.0 以降では削除された関数が含まれているため対応
export OMPI_MCA_mpi_compatibility=true
apt remove –purge mpi-default-bin mpi-default-dev
apt install openmpi-bin=1.10.7-1build1 openmpi-common=1.10.7-1build1 libopenmpi-dev=1.10.7-1build1
mkdir -p ~/build/esys-particle
cd ~/build/esys-particle
cmake -S ~/src/ESyS-Particle/esys-particle-trunk
make
make install
環境変数の設定
export PATH=/usr/local/bin/:$PATH
export LIBRARY_PATH=/usr/local/lib/:$LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH
export PYTHONPATH=/usr/local/lib/python3.8/dist-packages:/usr/local/lib/python3/dist-packages:$PYTHONPATH
mpirun -np 2 esysparticle ../Doc/Examples/two_particle.py
警告無視
export OMPI_ALLOW_RUN_AS_ROOT=1
export OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1
一般ユーザ追加
adduser mpiuser
su – mpiuser
mpirun -np 2 ./your_program
インストールの確認
mkdir ~/scratch
cd ~/scratch
mpirun -np 2 esysparticle ~/src/ESyS-Particle/esys-particle-trunk/Doc/Examples/two_particle.py
https://launchpad.net/esys-particle/+download#:~:text=ESyS%2DParticle%2D2.3.5.tar.gz
wget https://launchpad.net/esys-particle/+download#:~:text=ESyS%2DParticle%2D2.3.5.tar.gz
cd /usr/BUILD/sources
wget https://boostorg.jfrog.io/artifactory/main/release/1.52.0/source/boost_1_52_0.tar.bz2
tar –bzip2 -xf boost_1_52_0.tar.bz2
cd boost_1_52_0
./bootstrap.sh –prefix=/usr/BUILD –with-libraries=filesystem,python,regex,system
./b2
./b2 install
cd /usr/BUILD/sources
wget https://github.com/Kitware/CMake/releases/download/v3.22.0/cmake-3.22.0.tar.gz
tar xzf cmake-3.22.0.tar.gz
cd cmake-3.22.0
export CXXFLAGS=”-std=c++11″ export CFLAGS=”-std=c++11″
./configure –prefix=/usr/BUILD CXXFLAGS=”-std=c++11″
make
make install
/usr/BUILD/bin/cmake –version
sudo apt-get install libncurses5-dev
cd /usr/BUILD/sources
wget https://www.vtk.org/files/release/6.1/VTK-6.1.0.tar.gz
tar xzf VTK-6.1.0.tar.gz
mkdir /usr/BUILD/sources/VTK-build
cd /usr/BUILD/sources/VTK-build
cmake ../VTK-6.1.0 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/BUILD \
-DBUILD_SHARED_LIBS=ON \
-DVTK_WRAP_PYTHON=ON \
-DModule_vtkPython=ON \
-DModule_vtkPythonInterpreter=ON \
-DPYTHON_EXECUTABLE=/usr/bin/python2.7 \
-DPYTHON_INCLUDE_DIR=/usr/include/python2.7 \
-DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython2.7.so \
-DVTK_INSTALL_PYTHON_MODULE_DIR=/usr/BUILD/lib/python2.7/site-packages
sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev
ls /usr/include/python2.7/patchlevel.h
sudo apt-get install -y python2.7-dev
ls /usr/local/include/python2.6/patchlevel.h
apt-get install libxt-dev
make -j$(nproc)
make install
sudo apt-get install -y software-properties-common
sudo apt-get update
sudo apt-get install -y ca-certificates
sudo update-ca-certificates
cd /home/ubuntu/build/sources
wget https://cmake.org/files/v2.8/cmake-2.8.12.2.tar.gz
tar xfz cmake-2.8.12.2.tar.gz
cd cmake-2.8.12.2ß
./configure –prefix=/home/ubuntu/build
make
make install
sudo apt-get install -y gcc-7 g++-7
sudo apt-get install -y build-essential libgmp-dev libmpfr-dev libmpc-dev texinfo
wget https://ftp.gnu.org/gnu/gcc/gcc-7.5.0/gcc-7.5.0.tar.gz tar xzf gcc-7.5.0.tar.gz cd gcc-7.5.0 ./contrib/download_prerequisites
../configure –prefix=/usr/local/gcc-7.5 –enable-languages=c,c++ –disable-multilib make -j$(nproc) sudo make install
export PATH=/usr/local/gcc-7.5/bin:$PATH
gcc –version
../configure –prefix=/home/ubuntu/build/gcc-7.5.0 \
–enable-languages=c,c++ \
–disable-multilib \
–disable-libsanitizer
export PATH=/home/ubuntu/build/cmake-3.10.2/bin:$PATH
cmake ../sources/VTK-6.2.0 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/home/ubuntu/build/VTK-6.2 \
-DBUILD_SHARED_LIBS=ON \
-DVTK_USE_X=ON \
-DVTK_Group_StandAlone=ON \
-DVTK_Group_Rendering=ON \
-DVTK_USE_GL2PS=ON \
-DCMAKE_CXX_FLAGS=”-std=c++11 -Wno-register”
wget https://launchpad.net/esys-particle/trunk/3.0-alpha/+download/gengeo-163.tar.gz
tar -xzf gengeo-163.tar.gz
cd gengeo
bzr branch lp:esys-particle/gengeo
sudo apt-get update
sudo apt-get install -y autoconf automake libtool
from gengeo import RandomBoxPacker, Vec3, VtkSphereWriter
Define the simulation box dimensions (50 µm x 50 µm x 50 µm)
box_min = Vec3(0, 0, 0) # Minimum corner of the box
box_max = Vec3(50, 50, 50) # Maximum corner of the box
Define particle properties
particle_count = 50 # Number of particles to generate
particle_radius_min = 0.5 # Minimum particle radius (µm)
particle_radius_max = 1.0 # Maximum particle radius (µm)
Initialize the random particle packer
packer = RandomBoxPacker(
radiusMin=particle_radius_min, # Minimum particle radius
radiusMax=particle_radius_max, # Maximum particle radius
region=box_max – box_min, # Box dimensions
tolerance=0.01, # Tolerance for packing
numSpheres=particle_count # Number of particles to generate
)
Generate the particles
packer.generate()
Retrieve the generated particle data
particles = packer.getParticles()
Create a VTK writer to output the particles
output_file = “particles.vtk”
writer = VtkSphereWriter(output_file)
Add each particle to the VTK writer
for particle in particles:
writer.addSphere(
position=particle.position, # Position of the particle
radius=particle.radius # Radius of the particle
)
Write the particle data to the VTK file
writer.write()
print(f”Particle data has been saved to {output_file}.”)
apt-get update && apt-get install -y \
build-essential \
cmake \
libboost-all-dev \
python3 \
python3-dev \
python3-pip
import gmsh
import numpy as np
Gmsh 初期化
gmsh.initialize()
モデルのロード
gmsh.open(“simple_electromagnetic.geo”)
メッシュ生成 (2D)
gmsh.model.mesh.generate(2)
磁界の簡易計算 (単純なフィールド例)
注: 実際の電磁気解析は追加の数値解法ライブラリが必要
nodes = gmsh.model.mesh.getNodes()
x, y, z = nodes[1].reshape(-1, 3).T
簡単な磁界の計算(例: 磁場が z 軸方向に一様である場合)
Bx = np.zeros_like(x)
By = np.zeros_like(y)
Bz = np.ones_like(z) # 一様な z 軸方向磁場
メッシュノードごとに磁場を ParaView 用に保存
vtk_file = “simple_magnetic_field.vtk”
with open(vtk_file, “w”) as f:
# VTK ヘッダ
f.write(“# vtk DataFile Version 3.0\n”)
f.write(“Magnetic field data\n”)
f.write(“ASCII\n”)
f.write(“DATASET UNSTRUCTURED_GRID\n”)
f.write(f”POINTS {len(x)} float\n”)
for xi, yi, zi in zip(x, y, z):
f.write(f”{xi} {yi} {zi}\n”)
f.write(“\n”)
f.write(f”POINT_DATA {len(x)}\n”)
f.write(“VECTORS MagneticField float\n”)
for bxi, byi, bzi in zip(Bx, By, Bz):
f.write(f”{bxi} {byi} {bzi}\n”)
print(f”Magnetic field data saved to {vtk_file}”)
Gmsh の終了
gmsh.finalize()
// Gmsh スクリプト: 単純な 2D 平面で電磁気解析用メッシュ生成
// モデルの設定
SetFactory(“OpenCASCADE”);
// 四角形導体の作成 (幅 1×1 の領域)
Rectangle(1) = {0, 0, 0, 1, 1};
// 周囲の空間 (解析領域) を作成
Rectangle(2) = {-2, -2, 0, 5,å 5};
// メッシュ生成の設定
Physical Surface(“Conductor”) = {1};
Physical Surface(“Air”) = {2};
// メッシュを作成
Mesh 2;
// 結果を ParaView 用にエクスポート (VTK)
Save “simple_electromagnetic.vtk”;å
// モデルの設定
SetFactory(“OpenCASCADE”);
// 導体 (1×1 四角形)
Rectangle(1) = {0, 0, 0, 1, 1};
// 周囲の空気領域 (解析領域: 5×5)
Rectangle(2) = {-2, -2, 0, 5, 5};
// 導体を空気領域から引き算 (導体が空気の一部を占める構造にする)
BooleanDifference{ Surface{2}; Delete; }{ Surface{1}; Delete; }
// 物理領域を定義
Physical Surface(“Conductor”) = {1}; // 導体領域
Physical Surface(“Air”) = {2}; // 空気領域
// メッシュを生成
Mesh 2;
// ParaView 用に出力
Save “two_regions.vtk”;
SetFactory(“OpenCASCADE”);
// モデル領域を作成
Rectangle(1) = {0, 0, 0, 1, 1};
Rectangle(2) = {-2, -2, 0, 5, 5};
// サーフェスの差を作成
out[] = BooleanDifference{ Surface{2}; Delete; }{ Surface{1}; Delete; };
// 結果のタグを表示して確認
Printf(“Resulting surface tags: %g and %g”, out[0], out[1]);
// 物理領域を再定義
Physical Surface(“Conductor”) = {out[1]}; // 導体領域
Physical Surface(“Air”) = {out[0]}; // 空気領域
// メッシュ生成
Mesh 2;
// VTK 出力
Save “two_regions.vtk”;
// モデルの設定
SetFactory(“Built-in”);
// ポイントを定義
// 空気領域の四隅
Point(1) = {-2, -2, 0, 1.0};
Point(2) = {3, -2, 0, 1.0};
Point(3) = {3, 3, 0, 1.0};
Point(4) = {-2, 3, 0, 1.0};
// 導体領域の四隅
Point(5) = {0, 0, 0, 1.0};
Point(6) = {1, 0, 0, 1.0};
Point(7) = {1, 1, 0, 1.0};
Point(8) = {0, 1, 0, 1.0};
// ラインを定義
// 空気領域
Line(1) = {1, 2};
Line(2) = {2, 3};
Line(3) = {3, 4};
Line(4) = {4, 1};
// 導体領域
Line(5) = {5, 6};
Line(6) = {6, 7};
Line(7) = {7, 8};
Line(8) = {8, 5};
// ラインループを作成
Line Loop(1) = {1, 2, 3, 4}; // 空気領域
Line Loop(2) = {5, 6, 7, 8}; // 導体領域
// サーフェスを作成
Plane Surface(1) = {1}; // 空気領域
Plane Surface(2) = {2}; // 導体領域
// 物理領域を定義
Physical Surface(“Air”) = {1};
Physical Surface(“Conductor”) = {2};
// メッシュを生成
Mesh 2;
// VTK 出力
Save “line_based_structure.vtk”;
import gmsh
import numpy as np
import math
初期化
gmsh.initialize()
モデルを読み込む (Gmsh スクリプトで生成された .geo ファイル)
gmsh.open(“line_based_structure.geo”)
メッシュを生成 (2D)
gmsh.model.mesh.generate(2)
ノード情報を取得
node_tags, node_coords, _ = gmsh.model.mesh.getNodes()
座標を取得
node_coords = np.array(node_coords).reshape(-1, 3)
x_coords = node_coords[:, 0]
y_coords = node_coords[:, 1]
磁場計算: 簡易モデル (中心に単位電流を仮定)
mu_0 = 4 * math.pi * 1e-7 # 真空の透磁率
I = 1.0 # 電流 (1A と仮定)
Bx = np.zeros_like(x_coords)
By = np.zeros_like(y_coords)
for i, (x, y) in enumerate(zip(x_coords, y_coords)):
r = math.sqrt(x2 + y2)
if r > 0: # 自身の位置での無限大回避
B = mu_0 * I / (2 * math.pi * r) # 磁場の大きさ (円形電流の場合)
Bx[i] = -B * y / r # x成分
By[i] = B * x / r # y成分
結果を VTK ファイルとして保存 (ParaView 用)
output_filename = “magnetic_field.vtk”
with open(output_filename, “w”) as vtk_file:
vtk_file.write(“# vtk DataFile Version 3.0\n”)
vtk_file.write(“Magnetic field example\n”)
vtk_file.write(“ASCII\n”)
vtk_file.write(“DATASET UNSTRUCTURED_GRID\n”)
vtk_file.write(f”POINTS {len(x_coords)} float\n”)
for x, y in zip(x_coords, y_coords):
vtk_file.write(f”{x} {y} 0\n”)
vtk_file.write(f"\nPOINT_DATA {len(x_coords)}\n")
vtk_file.write("VECTORS MagneticField float\n")
for bx, by in zip(Bx, By):
vtk_file.write(f"{bx} {by} 0\n")
print(f”Magnetic field data saved to {output_filename}”)
終了
gmsh.finalize()
import gmsh
import numpy as np
Gmsh 初期化
gmsh.initialize()
gmsh.open(“line_based_structure.geo”)
メッシュを生成
gmsh.model.mesh.generate(2)
電気伝導率を定義
conductivity = {} # 領域ごとの電気伝導率を格納
領域の物理名を取得して電気伝導率を割り当て
entities = gmsh.model.getEntities(dim=2) # 2次元エンティティ (サーフェス)
for entity in entities:
name = gmsh.model.getPhysicalName(2, entity[1])
if name == “Air”:
conductivity[entity[1]] = 1e-12 # 空気の仮想的な電気伝導率
elif name == “Conductor”:
conductivity[entity[1]] = 5.96e7 # 銅の電気伝導率
設定された電気伝導率を確認
print(“Conductivity settings for regions:”)
for tag, value in conductivity.items():
print(f”Region {tag}: Conductivity = {value} S/m”)
ノード情報を取得
node_tags, node_coords, _ = gmsh.model.mesh.getNodes()
node_coords = np.array(node_coords).reshape(-1, 3)
ノードごとの電流密度と電場を計算
node_current_density = []
node_electric_field = []
for coord in node_coords:
# 仮想的に電場を線形分布と仮定
# 下: 0V, 上: 10V
if coord[1] == 3:
E = 10 / (3 – (-2)) # 電場の大きさ
elif coord[1] == -2:
E = 10 / (3 – (-2))
else:
E = 10 / (3 – (-2))
# 電流密度 = 電気伝導率 * 電場
J = 1e-12 * E # 空気層での仮定値(適宜変更可)
node_electric_field.append(E)
node_current_density.append(J)
VTK ファイルに電流密度と電場を保存
output_filename = “conductivity_simulation.vtk”
with open(output_filename, “w”) as vtk_file:
vtk_file.write(“# vtk DataFile Version 3.0\n”)
vtk_file.write(“Conductivity simulation\n”)
vtk_file.write(“ASCII\n”)
vtk_file.write(“DATASET UNSTRUCTURED_GRID\n”)
# ノード座標を書き出し
vtk_file.write(f”POINTS {len(node_coords)} float\n”)
for coord in node_coords:
vtk_file.write(f”{coord[0]} {coord[1]} {coord[2]}\n”)
vtk_file.write(“\n”)
# ノードごとの電場データを書き出し
vtk_file.write(f"POINT_DATA {len(node_coords)}\n")
vtk_file.write("SCALARS ElectricField float 1\n")
vtk_file.write("LOOKUP_TABLE default\n")
for E in node_electric_field:
vtk_file.write(f"{E}\n")
# ノードごとの電流密度データを書き出し
vtk_file.write("SCALARS CurrentDensity float 1\n")
vtk_file.write("LOOKUP_TABLE default\n")
for J in node_current_density:
vtk_file.write(f"{J}\n")
print(f”Simulation completed and saved to {output_filename}”)
Gmsh を終了
gmsh.finalize()
import gmsh
import numpy as np
Gmsh 初期化
gmsh.initialize()
gmsh.open(“line_based_structure.geo”)
メッシュを生成
gmsh.model.mesh.generate(2)
電位の計算のための準備
下部のライン(AirBottom)を 0V、上部のライン(AirTop)を 10V と設定
voltage = {} # 境界ごとの電圧を格納
境界ラインのエンティティを取得
entities = gmsh.model.getEntities(dim=1) # 1次元エンティティ (ライン)
for entity in entities:
name = gmsh.model.getPhysicalName(1, entity[1])
if name == “AirBottom”: # 空気層の下界面
voltage[entity[1]] = 0 # 0V
elif name == “AirTop”: # 空気層の上界面
voltage[entity[1]] = 10 # 10V
設定された電圧を確認
print(“Voltage settings for boundaries:”)
for tag, value in voltage.items():
print(f”Boundary {tag}: Voltage = {value} V”)
ノード情報を取得
node_tags, node_coords, _ = gmsh.model.mesh.getNodes()
node_coords = np.array(node_coords).reshape(-1, 3)
電位ポテンシャルの計算
node_potentials = []
for coord in node_coords:
# 下: 0V、上: 10V
if coord[1] == 3: # y=3 は AirTop
node_potentials.append(10)
elif coord[1] == -2: # y=-2 は AirBottom
node_potentials.append(0)
else:
# 線形補間で中間の電位を計算
potential_at_node = 10 * (coord[1] – (-2)) / (3 – (-2))
node_potentials.append(potential_at_node)
VTK ファイルに電位ポテンシャルを保存
output_filename = “conductivity_simulation_with_potential.vtk”
with open(output_filename, “w”) as vtk_file:
vtk_file.write(“# vtk DataFile Version 3.0\n”)
vtk_file.write(“Conductivity simulation with potential\n”)
vtk_file.write(“ASCII\n”)
vtk_file.write(“DATASET UNSTRUCTURED_GRID\n”)
# ノード座標を書き出し
vtk_file.write(f”POINTS {len(node_coords)} float\n”)
for coord in node_coords:
vtk_file.write(f”{coord[0]} {coord[1]} {coord[2]}\n”)
vtk_file.write(“\n”)
# ノードごとの電位ポテンシャルデータを書き出し
vtk_file.write(f"POINT_DATA {len(node_coords)}\n")
vtk_file.write("SCALARS Potential float 1\n")
vtk_file.write("LOOKUP_TABLE default\n")
for potential in node_potentials:
vtk_file.write(f"{potential}\n")
print(f”Voltage potential simulation completed and saved to {output_filename}”)
Gmsh を終了
gmsh.finalize()