OpenFOAMカスタマイズのためのVSCode設定

# 概要
OpenFOAMをカスタマイズする際に，VSCodeを簡易的なIDEとして用い，いくつかのコマンド実行をマウス作業に置き換えられないか検討しました．VSCodeのワークスペースや拡張機能を利用することで，ある程度それが実現可能だと判ったので，そのやり方をまとめます．

## 使用した機能
- エクスプローラー，ツリービュー
  - フォルダーを開く
  - ファイル・フォルダーの新規作成
  - ファイル・フォルダーの名前の変更（<kbd>F2</kbd>）
  - ファイル・フォルダーのコピー＆貼り付け（<kbd>Ctrl</kbd>+<kbd>C</kbd>, <kbd>Ctrl</kbd>+<kbd>V</kbd>）
  - フォルダー内を検索（<kbd>Shift</kbd>+<kbd>Alt</kbd>+<kbd>F</kbd>）
  - ファイルへ移動（<kbd>Ctrl</kbd>+<kbd>P</kbd>）
- ワークスペース
  - code-workspaceファイル
  - フォルダをワークスペースに追加
- ターミナル
- C/C++拡張機能
  - 設定ファイル`c_cpp_properties.json`
    - `includePath`
    - `defines`
  - VSCodeの変数`${workspaceFolder}`

# 環境
- Windows 10
- VSCode 1.66.0 (user setup)
    - Remote - WSL v0.66.0
    - C/C++ v1.9.7
    - C/C++ Extension Pack v1.1.0
- Ubuntu 20.04 (on WSL)
- OpenFOAM v2106 (aptにてインストール)

本記事では，実質的に作業を全てLinuxで行っています．
Windowsでも同じように設定はできますが，パスのセパレータが`/`から`\`に変わるので，パスを指定する際に`\`をエスケープする（`\\`に置き換える）必要があります．また，VSCodeの標準の文字エンコードにはUTF-8を想定しているので，WindowsでVSCodeの文字エンコードにShift-JISを採用している場合は，問題が生じる可能性があります．

# OpenFOAMカスタマイズ
OpenFOAMはオープンソースの熱流体解析ソフトウェアです．広範な現象，複雑形状周りの流れを計算できること，何より使用に際して費用が発生しないため，広く使われています[^oss]．既に実装されている機能だけでも多くの現象を計算できますが，ソースを入手して，自身で新しい機能を追加できます．しかし，OpenFOAMは多機能である分，ディレクトリ構造やソース内の参照関係などが簡潔ではないため，プログラミング・数値解析初心者が手を出すには少々難易度が高いように感じます．

[^oss]: 使用料が無料でも，使い方の調査や問題解決は自力で行う必要があります．使用料を問題解決のための人件費で置き換えているのが実態だと思います．本当に安くなるかは慎重に検討した方がよいでしょう．

幸いなことに，富山県立大学 工学部 機械システム工学科 熱流体工学講座の中川先生が[OpenFOAMカスタマイズの始め方(v1912)](https://nakagawa-lab.kibe.la/shared/entries/003fe2b2-1faa-4ce6-b95a-2265d3765d7b)というページを公開されています．OpenFOAMのバージョンは異なりますが，v2106でもまったく修正が必要なかったので，この始め方に倣ってカスタマイズを行いつつ，その作業を簡略化（特にLinuxコマンド入力をGUIでの作業に置き換え）できないかを検討しました．

このような知見を整理して公開してくれる先生がおり，やる気は満々で自学自習を厭わない学生がいるのは素晴らしいことだと思います．

## 作業内容
[OpenFOAMカスタマイズの始め方(v1912)](https://nakagawa-lab.kibe.la/shared/entries/003fe2b2-1faa-4ce6-b95a-2265d3765d7b)では，作業内容として

1. 準備
1. 新しい名前のソルバ作成
1. テスト用例題の作成
1. ライブラリのカスタマイズとモデルの改造
1. 例題の作成

となっています．

このうち，準備，ライブラリのカスタマイズについて作業内容を確認し，VSCode上で作業していきます[^consent]．
[^consent]: 内容を部分的に参照することは，ページの作成者である富山県立大学中川先生からご許可いただいています．

### 準備
1. OpenFOAMのインストールディレクトリ（`$WM_PROJECT_DIR`）の確認
1. OpenFOAMのカスタマイズで用いるユーザディレクトリ（`$WM_PROJECT_USER_DIR`）の確認と作成

### ライブラリのカスタマイズとモデルの改造
1. OpenFOAMの粘性モデル`transportModels/incompressible/viscosityModels/CrossPowerLaw/`をコピーし，名前を変更
1. コンパイルと生成されたライブラリの確認
1. `CrossPowerLaw`モデルの改造

# VSCodeでの作業と設定
## Ubuntuへのログイン
WSLではなく，仮想マシンや実マシンでLinuxにログインしている方は，この作業は不要です．

### Remote-WSL拡張のインストール
VSCodeからWSLのUbuntuにログインするために，Remote-WSL拡張をインストールします．

### Ubuntuへのログイン
VSCodeの左下にある`≷`のような記号をクリックし，`New WSL Window`（WSLに複数の環境がある場合は`New WSL Window using Distro...`）を選択すると，新たにVSCodeのウィンドウが開きます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/8b2cae1a-ca23-c047-85d2-0af2774febbb.png)
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/8796ecaf-2bfb-cc16-21c4-c39f8788f1c6.png)
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/38c2c320-f328-4015-1e10-0a934e2e61ae.png)


このVSCodeは，WSL上のUbuntuにログインした状態になっており，左下の`≷`記号の隣に，WSL: Ubuntu-20.04などリモートログインしている環境の名前が表示されます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/5fb65a6c-a6a0-755a-96cf-665fe3747061.png)


## 環境変数の確認
画面左にあるサイドバーから，エクスプローラー（一番上）を開き，フォルダを開くボタンをクリックします．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/e85f6a35-a5dd-7136-84dd-c0a9dd824bba.png)
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/aa61acbe-0ce0-9254-8ddf-c1c6a71ff79e.png)

ホームディレクトリを開くと，ツリービューにホームディレクトリの内容が表示されます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/7e763453-1a39-b489-2f9e-a06f1b7c4c88.png)

ここで`.bashrc`に設定を追加して，OpenFOAMの環境変数を簡単に有効化できるようにします．，ファイルの一覧から`.bashrc`をクリックすると，ファイルが開かれてエディタウィンドウにファイル内容が表示されます．`apt`でOpenFOAMをインストールすると，インストールパスは`/usr/lib/openfoam/openfoam2106`になり，その下の`/etc/bashrc`に環境変数の設定が書かれています．これを`of2106-setvars`というコマンドで実行できるようにします．

```bash
# enable OpenFOAM v2106 environment variables
alias of2106-setvars='. /usr/lib/openfoam/openfoam2106/etc/bashrc'
```

編集終了後，上部メニューの[ファイル]→[保存]もしくは<kbd>Ctrl</kbd>+<kbd>S</kbd>で`.bashrc`を保存して閉じた後，上部のメニューから[表示]→[ターミナル]を選択し，ターミナルを開きます．VSCodeからフォルダを開いておけば，ターミナルのカレントディレクトリはその開いたフォルダになります．

ここで，先ほど設定したコマンド`of2106-setvars`を実行した後，`$WM_PROJECT_DIR`を表示することで，環境変数が正しく読み込まれたかを確認できます．

```shell
~$ echo $WM_PROJECT_DIR

~$ of2106-setvars
~$ echo $WM_PROJECT_DIR
/usr/lib/openfoam/openfoam2106
~$
```

## ディレクトリの作成とワークスペースへの登録
### カスタマイズ用ユーザディレクトリの作成
次に，OpenFOAMの環境変数である`$WM_PROJECT_USER_DIR`を確認します．

```shell
~$ echo $WM_PROJECT_USER_DIR
/home/ユーザ名/OpenFOAM/ユーザ名-v2106
~$
```

このディレクトリが存在していない場合，作成する必要があります．

ツリービューの上の方に，ディレクトリに+記号が付いたアイコンがあるので，それをクリックすると新しいディレクトリが作成されます[^newfolder]．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/29c93708-ddea-fce5-80ab-70eff0e4a002.png)


ディレクトリの名前欄に`OpenFOAM`と入力して<kbd>Enter</kbd>を押すと，ディレクトリが新しく作られます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/77c1f76e-de92-975a-b6c6-fab322ee6deb.png)


[^newfolder]: ディレクトリを開いている状態だと，そのディレクトリの下に新しいフォルダが作られてしまうので気をつけてください．

その後，OpenFOAMディレクトリをクリックした後，そのディレクトリ下に同じように新しいディレクトリを作成します．ディレクトリ名は，`$WM_PROJECT_USER_DIR`の設定に合わせて`ユーザ名-v2106`とし，<kbd>Enter</kbd>を押します．

これでOpenFOAMのカスタマイズ作業をするためのディレクトリが作成されました．`~/OpenFOAM/ユーザ名-v2106`をユーザディレクトリとよぶことにします．

### VSCodeワークスペースへのディレクトリの登録
VSCodeにはワークスペースという機能があり，複数のフォルダをまとめて表示したり，ワークスペース固有の設定を設けたりできます．

このワークスペースに`$WM_PROJECT_DIR`と`$WM_PROJECT_USER_DIR`を登録し，ファルのコピーなどを簡単にしようという目論見です．

ツリービューで，先ほど作成した`~/OpenFOAM/ユーザ名-v2106`を開いている状態にした後，ディレクトリの新規作成をしたアイコンの左隣にあるアイコンを選択します．これは，選択したディレクトリ内にファイルを新しく作るアイコンです．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/cbdb4c01-3b3a-ff0b-d0e8-4031f6727089.png)

ファイル名に，例えば`of2106customize.code-workspace`と付けます．このファイル名は何でもいいのですが，ファイル名末尾は`.code-workspace`で終わるようにしてください．このファイルをワークスペース設定とよぶことにします．

作成したファイルに，下記の内容を貼り付けて保存します．

```json:of2106customize.code-workspace
{
	"folders": [
		{
			"path": "."
		}
	]
}
```

ワークスペース設定（末尾が`.code-workspace`で終わるファイル）をVSCodeで開くと，エディタウィンドウの右下の方に，[ワークスペースを開く]というボタンが常に現れるようになります．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/f4c0dffc-39bc-31ca-e1f6-8065f13249d9.png)


[ワークスペースを開く]をクリックすると，ツリービューの表示が変わります．今まで開いていたホームディレクトリではなく，`ユーザ名-v2106`が開かれています．これは先ほど作成した`~/OpenFOAM/ユーザ名-v2106`ディレクトリです．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/d7139c17-892c-6fff-f307-924db8deed52.png)

次に，上部のメニューから，[ファイル]→[フォルダをワークスペースに追加]を選択し，`$WM_PROJECT_DIR`，つまり`/usr/lib/openfoam/openfoam2106/`を追加します．[フォルダをワークスペースに追加]を選択するとディレクトリパスを入力するメニューが表示されるので，パスを直接入力するか，枠の下に表示されているツリーを辿ってディレクトリを選択し，[OK]を押します．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/976efa52-f6fc-3c0e-4e7c-ed472b374f29.png)


ツリービューに`openfoam2106`ディレクトリが追加されます．これでディレクトリ探索や，カスタマイズのためのコピーが手軽に行えるようになります．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/2ae80226-b63c-5941-085c-812aaa2be1f9.png)


## カスタマイズするソースのコピーと専用のワークスペースの作成
### ソースのコピーと名前の変更
粘性モデル`transportModels/incompressible/viscosityModels/CrossPowerLaw/`をカスタマイズするために，`CrossPowerLaw`ディレクトリをユーザディレクトリにコピーし，名前を変更します．

ツリービューから，`openfoam2106`→`src`→`transportModels`→`incompressible`→`viscosityModels`と辿っていき，`CrossPowerLaw`ディレクトリを選択してコピーします．右クリック→コピーでも<kbd>Ctrl</kbd>+<kbd>C</kbd>でもコピーできます．

その後，ユーザディレクトリ（`ユーザ名-v2106`）を選択して`src`ディレクトリを作成した後，コピーした`CrossPowerLaw`ディレクトリを貼り付けます．`src`ディレクトリを選択し，右クリック→貼り付けでも<kbd>Ctrl</kbd>+<kbd>V</kbd>でも可能です．

貼り付けた`CrossPowerLaw`ディレクトリを選択し，右クリック→[名前の変更]を選択するか<kbd>F2</kbd>を押すことで，ディレクトリ名を変更できるようになります．ここでは，`newCrossPowerLaw`と変更します．ソースファイル`CrossPowerLaw.C`および`CrossPowerLaw.H`も同じように`newCrossPowerLaw.C`および`newCrossPowerLaw.H`に変更します．

その後，作成するライブラリの名前が衝突しないよう，ソースファイル内の情報を変更します．`newCrossPowerLaw`ディレクトリを選択し，右クリック→[フォルダー内を検索]もしくは<kbd>Shift</kbd>+<kbd>Alt</kbd>+<kbd>F</kbd>を押し，検索ビューを開きます．

上から一つ目のボックス（検索）に`CrossPowerLaw`，二つ目のボックス（置換）に`newCrossPowerLaw`を入力します．上から三つ目のボックス（含めるファイル）が`./ユーザ名-v2106/src/newCrossPowerLaw`になっていることを確認し，二つ目のボックス右にある[すべて置換]ボタンを押すことで，`newCrossPowerLaw`ディレクトリ下の`newCrossPowerLaw.C`および`newCrossPowerLaw.H`内の`CrossPowerLaw`が`newCrossPowerLaw`に置換されます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/a139862a-ab9e-6d81-b278-4dfe49b5a13e.png)

このように名前を変更することで，ビルドした際に作成されるライブラリ名が`newCrossPowerLaw.so`となり，既存の`CrossPowerLaw.so`とは衝突しなくなります．

### newCrossPowerLaw専用ワークスペースの作成
さて，ここでソースをカスタマイズできる状態になったわけですが，もう一度ワークスペースを作成します．少し面倒だと思うかも知れませんが，専用のワークスペースを作成した方が，何かと恩恵があります．

上で行った作業と同じように，`newCrossPowerLaw`ディレクトリ内にワークスペースファイルを作成します．ファイルを新規作成し，`newCrossPowerLaw.code-workspace`と名付けます．作成したファイルに，下記の内容を貼り付けて保存したのち，エディタウィンドウ右下の[ワークスペースを開く]ボタンを選択します．

```json:newCrossPowerLaw.code-workspace
{
	"folders": [
		{
			"path": "."
		}
	]
}
```

次に，[ファイル]→[フォルダをワークスペースに追加]を選択し，`/usr/lib/openfoam/openfoam2106/`を追加しておきます．

作成済みのワークスペース設定`of2106customize.code-workspace`をコピーして名前を変えればよいと思われるかもしれませんが，設定に書くフォルダのパスは，その`code-workspace`ファイルからの相対パスなので，単純に流用はできません．

## ビルド設定のコピーとビルド
### ビルド設定のコピー
OpenFOAMでは，ビルドをする際に`Make`ディレクトリ内にある`files`, `options`を参照します．newCrossPowerLawにはそのディレクトリがないため，既存の設定をコピーします．

ツリービューから，`openfoam2106`→`src`→`transportModels`→`incompressible`と辿っていき，`Make`ディレクトリをコピーし，`newCrossPowerLaw`ディレクトリに貼り付けます．

そのままでは設定が全く異なるので，内容を編集します．`Make/files`は，ビルドするソースファイルのパスと，出力されるライブラリのパス設定を記述します．元ファイルからいくつか不要な記述を削除し，ライブラリの出力パス設定や名前を変更します．

```Makefile:Make/files
newCrossPowerLaw.C

LIB = $(FOAM_USER_LIBBIN)/libnewCrossPowerLaw
```

変更差分は下記のとおりです．

```diff
- viscosityModels/viscosityModel/viscosityModel.C
- viscosityModels/viscosityModel/viscosityModelNew.C
- viscosityModels/Newtonian/Newtonian.C
- viscosityModels/powerLaw/powerLaw.C
- viscosityModels/CrossPowerLaw/CrossPowerLaw.C
+ newCrossPowerLaw.C
- viscosityModels/BirdCarreau/BirdCarreau.C
- viscosityModels/HerschelBulkley/HerschelBulkley.C
- viscosityModels/Casson/Casson.C
- viscosityModels/strainRateFunction/strainRateFunction.C
- viscosityModels/Arrhenius/Arrheniuss.C
-
- transportModel/transportModel.C
- singlePhaseTransportModel/singlePhaseTransportModel.C
-
- incompressibleTwoPhaseMixture/incompressibleTwoPhaseMixture.C

- LIB = $(FOAM_LIBBIN)/libincompressibleTransportModels
+ LIB = $(FOAM_USER_LIBBIN)/libnewCrossPowerLaw
```

`Make/options`は，インクルードディレクトリとリンクするライブラリを，コンパイルオプションの形で記述します．

```Makefile:Make/options
EXE_INC = \
    -I$(LIB_SRC)/transportModels/incompressible/lnInclude \
    -I$(LIB_SRC)/finiteVolume/lnInclude

LIB_LIBS = \
    -lfiniteVolume
```

変更差分は下記のとおりです．

```diff
EXE_INC = \
-    -I.. \
-    -I../twoPhaseMixture/lnInclude \
+    -I$(LIB_SRC)/transportModels/incompressible/lnInclude \
-    -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/finiteVolume/lnInclude
-    -I$(LIB_SRC)/meshTools/lnInclude

LIB_LIBS = \
-    -ltwoPhaseMixture \
    -lfiniteVolume
```

ファイルを編集して保存できたら，ビルドを実行します．

### ビルド
ビルドには`wmake`を用います．`wmake`を実行する前に，**OpenFOAMの環境設定を読み込むことを忘れないでください**．ワークスペースを開くとログイン直後の状態に戻ってしまうので，ログイン後に手動で読み込んだ環境変数はもう一度読み込み直す必要があります．

[表示]→[ターミナル]でターミナルを開きます．このとき，カレントディレクトリが`newCrossPowerLaw`ディレクトリになっているはずです．

`of2106-setvars`を実行したあと，`wmake`を実行すると，ビルドが行われます．ビルド時にエラーが出力されず，出力ディレクトリ`$FOAM_USER_LIBBIN`にライブラリファイル`libnewCrossPowerLaw.so`が作成されていれば成功です．

```console
~/OpenFOAM/ユーザ名-v2106/src/newCrossPowerLaw$ of2106-setvars
~/OpenFOAM/ユーザ名-v2106/src/newCrossPowerLaw$ wmake
    ln: ./lnInclude
Making dependency list for source file newCrossPowerLaw.C
g++ -std=c++14 -m64 -pthread -DOPENFOAM=2106 -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -Wno-attributes -Wno-unknown-pragmas  -O3  -DNoRepository -ftemplate-depth-100 -I/usr/lib/openfoam/openfoam2106/src/transportModels/incompressible/lnInclude -I/usr/lib/openfoam/openfoam2106/src/finiteVolume/lnInclude -iquote. -IlnInclude -I/usr/lib/openfoam/openfoam2106/src/OpenFOAM/lnInclude -I/usr/lib/openfoam/openfoam2106/src/OSspecific/POSIX/lnInclude   -fPIC -c newCrossPowerLaw.C -o Make/linux64GccDPInt32Opt/newCrossPowerLaw.o
g++ -std=c++14 -m64 -pthread -DOPENFOAM=2106 -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -Wno-attributes -Wno-unknown-pragmas  -O3  -DNoRepository -ftemplate-depth-100 -I/usr/lib/openfoam/openfoam2106/src/transportModels/incompressible/lnInclude -I/usr/lib/openfoam/openfoam2106/src/finiteVolume/lnInclude -iquote. -IlnInclude -I/usr/lib/openfoam/openfoam2106/src/OpenFOAM/lnInclude -I/usr/lib/openfoam/openfoam2106/src/OSspecific/POSIX/lnInclude   -fPIC -shared -Xlinker --add-needed -Xlinker --no-as-needed  Make/linux64GccDPInt32Opt/newCrossPowerLaw.o -L/usr/lib/openfoam/openfoam2106/platforms/linux64GccDPInt32Opt/lib \
    -lfiniteVolume  -o /home/ユーザ名/OpenFOAM/ユーザ名-v2106/platforms/linux64GccDPInt32Opt/lib/libnewCrossPowerLaw.so
~/OpenFOAM/ユーザ名-v2106/src/newCrossPowerLaw$ ls $FOAM_USER_LIBBIN/libnewCrossPowerLaw.so
/home/ユーザ名/OpenFOAM/ユーザ名-v2106/platforms/linux64GccDPInt32Opt/lib/libnewCrossPowerLaw.so
~/OpenFOAM/ユーザ名-v2106/src/newCrossPowerLaw$
```

## カスタマイズ用の設定
ここまではワークスペースを作成して，主にファイルのコピーなどをGUIで作業できるようにしてきました．

これ以降は，ソースを編集する際に役に立つような設定を行っていきます．作業は，変わらずnewCrossPowerLawのワークスペースで行います．参考にしている[OpenFOAMカスタマイズの始め方(v1912)](https://nakagawa-lab.kibe.la/shared/entries/003fe2b2-1faa-4ce6-b95a-2265d3765d7b)の，モデルの更なる改良の節と同じようにファイルを編集することにします．

### VSCodeのC/C++設定ファイルの作成
#### インクルードパスの設定
`newCrossPowerLaw.C`や`newCrossPowerLaw.H`を開くと，いくつかエラーが表示されます．特に，`#inclue`ディレクティブでファイルを読み込んでいるところで，ファイルが見つからないというエラーが生じています．このエラーの原因は，`#include`で指定したヘッダファイルを探索するディレクトリが指定されていないことです．また，このエラーは，VSCodeの拡張機能がソースファイルの内容をバックグラウンドで解析し，そこで生じた結果として表示されています．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/1fe5e83c-773a-01fb-d905-ea12b840e92a.png)


ヘッダファイルを探索するディレクトリを指定するために，VSCodeの設定ファイルを作成します．

設定ファイルは，`newCrossPowerLaw`（ワークスペースで開かれるディレクトリ）直下に`.vscode`ディレクトリを作成し，`c_cpp_properties.json`という名前のファイルを新規に作成します．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/667cc6b8-d331-a0e9-3305-6ae05c0b8f18.png)

とりあえず，最も簡単な設定を記述（あるいはコピペ）して保存してください．

```json:c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Linux"
        }
    ]
}
```

保存すると，実行している環境に応じた設定が追記されます．著者の環境では，下記のように設定が追加されました．

```json:c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Linux",
            "intelliSenseMode": "linux-gcc-x64",
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "gnu17",
            "cppStandard": "gnu++14"
        }
    ],
    "version": 4
}
```

これでソースコードの解析する際の最低限の設定が行われました．この設定に，インクルードするファイルが存在するパスの設定を追加します．とりあえず，現在判っているディレクトリを追加します．

1. `newCrossPowerLaw.C`は同じディレクトリの`newCrossPowerLaw.H`を読み込んでいるので，`newCrossPowerLaw`ディレクトリを追加する必要があります．
1. `Make/options`をみると，`-I$(LIB_SRC)/transportModels/incompressible/lnInclude`の指定があるので，`$WM_PROJECT_DIR/src/transportModels/incompressible/lnInclude`を追加する必要があります．
1. 同じく`-I$(LIB_SRC)/finiteVolume/lnInclude`の指定があるので，`$WM_PROJECT_DIR/src/finiteVolume/lnInclude`を追加する必要があります．

設定項目として`"configurations.includePath"`を追加し，その値として上記3ディレクトリを追加します．

```json:c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}",
                "/usr/lib/openfoam/openfoam2106/src/transportModels/incompressible/lnInclude",
                "/usr/lib/openfoam/openfoam2106/src/finiteVolume/lnInclude"
            ],
            "intelliSenseMode": "linux-gcc-x64",
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "gnu17",
            "cppStandard": "gnu++14"
        }
    ],
    "version": 4
}
```

ここで，`${workspaceForlder}`はVSCodeの変数で，VSCodeで開かれているディレクトリのパスに置き換えられます．今回，複数のディレクトリ（`$WM_PROJECT_USER_DIR/src/newCrossPowerLaw`と`$WM_PROJECT_DIR`）を開いていますが，最初のディレクトリのパスに置き換えられるようです．~~`/**`は，そのディレクトリ以下を再帰的に探索することを意味します．~~（`/**`を付けるとヘッダファイルがうまく読み込まれない場合があることがわかりましたので，この1行は削除しました．）

さて，これでエラーが解消するかと期待してソースファイルを開いても，相変わらずエラーが表示されます．しかしエラーの内容が変化しており，例えば`newCrossPowerLaw.H`では，`#include "viscosityModel.H"`で`viscosityModel.H`自体が見つからないというエラーが，`viscosityModel.H`内で参照されている`dictionary.H`が見つからないというエラーになっています．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/3378a006-e7b5-2fb6-20ff-cb1a806a0a3f.png)

なら`dictionary.H`を見つけてやればよいということで，<kbd>Ctrl</kbd>+<kbd>P</kbd>を入力してVSCodeのファイル検索と移動機能を呼び出し，ファイル名`dictionary.H`を検索すると，`src/OpenFOAM/lnIncluce`にあることが判ります．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/f1e7fd1b-3fc3-53b3-4698-0cd34e81c221.png)

上図の検索候補の上から2番目を選択すると，`dictionary.H`がエディタウィンドウに開かれると共に，ツリービューで`dictionary.H`が選択された状態になります．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/f00603c0-3352-052c-a8e4-2b5c55914c46.png)

`dictionary.H`を含むディレクトリが表示されるまでツリービューを上にスクロールし，ディレクトリ（`lnInclude`）が表示されたら，ディレクトリを選択して右クリック→[パスのコピー]もしくは<kbd>Shift</kbd>+<kbd>Alt</kbd>+<kbd>C</kbd>でディレクトリのパスをコピーします．

コピーしたパスを，`includePath`に貼り付けてパスを追加します．

いくつかのエラーは消えますが，相変わらず`#include "viscosityModel.H"`でエラーが表示されます．次は，`viscosityModel.H`内で参照されている`regExp.H`が見つからないというエラーです．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/f5673403-076e-6986-5a64-8b9e3692baca.png)


同じように`regExp.H`を探し，そのパスを`includePath`に追加します．ファイルは`src/OSspecific/POSIX/lnInclude`にあると，VSCodeが見つけてくれます．同じ名前のファイルが`src/OSspecific/MSwindows/lnInclude`にもありますが，現在カスタマイズを行っている環境のOSはUbuntuなので，POSIXの方を選択します．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/23101dfd-aaf1-7fdc-50dc-6a1e9a478465.png)

最終的に，`includePath`の設定は下記のようになりました．

```json
            "includePath": [
                "${workspaceFolder}/**",
                "/usr/lib/openfoam/openfoam2106/src/transportModels/incompressible/lnInclude",
                "/usr/lib/openfoam/openfoam2106/src/finiteVolume/lnInclude",
                "/usr/lib/openfoam/openfoam2106/src/OpenFOAM/lnInclude",
                "/usr/lib/openfoam/openfoam2106/src/OSspecific/POSIX/lnInclude"
            ],
```

#### プリプロセッサ識別子の設定
`#inlcude`に関係するエラーは表示されなくなりましたが，未だにエラーが表示されます．

`newCrossPowerLaw.H`では，114行目で`label`が型の名前ではないというエラーが表示されます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/6fa095d1-dbb0-dc43-052e-b979537894f8.png)

また，`newCorssPowerLaw.C`では，56行目で識別子`scalar`が定義されていないというエラーと，84行目で，不完全なクラス型は使用できないというエラーが表示されます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/31adf4a9-ef2d-8613-da98-e527571691b9.png)
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/0dc2433f-ca6d-4464-5fa2-8692485d06b9.png)

これらのエラーの原因を直接的に示すことはしませんが，色々と調査した結果，ビルド時に`-D`で定義するプリプロセッサ識別子が認識されていないことが原因であることが判りました．

`wmake`でビルドしたときのコンソール出力を見ると，`-DOPENFOAM=2106`, `-DWM_DP`, `-DWM_LABEL_SIZE=32`, `-DNoRepository`の合計4個のプリプロセッサ識別子が定義されていました．これらを設定に追加することで，エラーを解消します．

解析時にプリプロセッサ識別子を定義するには，`c_cpp_properties.json`に`"defines"`という設定項目を追加します．

```json:c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "/usr/lib/openfoam/openfoam2106/src/transportModels/incompressible/lnInclude",
                "/usr/lib/openfoam/openfoam2106/src/finiteVolume/lnInclude",
                "/usr/lib/openfoam/openfoam2106/src/OpenFOAM/lnInclude",
                "/usr/lib/openfoam/openfoam2106/src/OSspecific/POSIX/lnInclude"
            ],
            "intelliSenseMode": "linux-gcc-x64",
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "gnu17",
            "cppStandard": "gnu++14",
            "defines": ["WM_LABEL_SIZE=32", "WM_DP", "NoRepository", "OPENFOAM=2106"]
        }
    ],
    "version": 4
}
```

面白いことに，上記の3個のエラーのうち，`label`に関するエラーは`WM_LABEL_SIZE=32`を設定すると消え，`scalar`に関するエラーは`WM_DP`，`U_`に関するエラーは`NoRepository`を設定すると消えました．

### ソースのカスタマイズ
これでエラーがない状態になりました．つまり，エラーがない状態が`wmake`でビルドできる状態と対応付けられたので，ここからソースファイルを編集してもエラーが表示されなければ，自身がミスをしてない状態であることが（完全ではないにしても）保証されます．ファイル編集後，ビルドしてみるまでエラーがあるか判らないという状態ではないので，開発の効率も上がると期待できます．

[OpenFOAMカスタマイズの始め方(v1912)](https://nakagawa-lab.kibe.la/shared/entries/003fe2b2-1faa-4ce6-b95a-2265d3765d7b)に沿って，`newCrossPowerLaw.H`および`newCrossPowerLaw.C`を編集します．

編集中もVSCodeの恩恵を受けることができます．`volScalarField`を入力している最中，IntelliSense機能によって入力が補完されます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/f2c6f03d-23a9-67fb-c1fc-8f48fef2a753.png)

また，`newCrossPowerLaw.H`内で定義されているメンバ関数`calcNu()`のプロトタイプ宣言の修正（`const`のコメントアウト）を忘れた状態で`newCrossPowerLaw.C`の`calcNew()`の実装を変更すると，プロトタイプ宣言と矛盾があることを適切に教えてくれます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/c9e0813e-05fb-84f2-5e13-f1ea33619b73.png)

ファイルの編集が終わったら，ファイルを保存してターミナルを開き，`wmake`を実行します．エラーが指摘されていなければ，高い確率でビルドは成功します．ただし，意図した動作をするかは，別途確認する必要はあります．

### `newCrossPowerLaw`用のワークスペースを作成した理由
せっかくカスタマイズ用のワークスペース`of2106customize.code-workspace`を作ったのに，改めて`newCrossPowerLaw`用のワークスペースを作成したのは，カスタマイズするソルバやライブラリに応じて`c_cpp_properties.json`の設定を使い分けるためです．

`of2106customize.code-workspace`でも`ユーザ名-v2106/.vscode`ディレクトリを作成して`c_cpp_properties.json`に設定を記述することは可能ですが，ソルバやライブラリに応じて使い分けることができません．

今回は`src/CrossPowerLaw`のみのカスタマイズを行いましたが，例えばsimpleFoamのカスタマイズをするために，`src/simpleFoam`を追加した場合，一つの`c_cpp_properties.json`にCrossPowerLaw用の設定（`includePath`や`defines`）とsimpleFoam用の設定を追加することになり，設定が煩雑化します．場合によっては，設定が衝突することも考えられます．

ディレクトリの作成やファイルコピーよりも，ソルバやライブラリのカスタマイズの方が難易度が高く，取り組む時間も長いことは容易に想像できます．その作業を少しでも簡略化するために，多少作業の手間が増えますが，カスタマイズするライブラリ用のワークスペースを作成することにしました．

# まとめ
OpenFOAMのカスタマイズの際に，VSCodeをIDEとして使えないかを検討しました．その結果，完全ではありませんが，ある程度使用感を改善できることが判りました．

- ワークスペースの機能を利用することで，複数のディレクトリをまとめてツリー表示でき，ファイルのコピー＆ペーストがGUIでできる．
- VSCodeのエクスプローラー機能を利用することで，ファイルやディレクトリの新規作成，名前の変更がGUIでできる．
- ツリー表示のファイルをクリックするだけでファイルを開いてくれる．当然編集もできる．
- ファイル内容の一括置換や，ワークスペース内のファイルの検索が楽にできる．
- C/C++用の設定を作成することで，インクルードするファイルの検索やコードの解析が実行され，エラーを指摘してくれる．

追加でやりたいこと
- `wmake`をタスクに登録し，ショートカットキーでビルドを実行する．