in the blue shirt.com

// —————————-
// 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()