        //-----------------------------------------------
        //
        //      cont_couplingSource_fsi
        //
        //      fsi用のsourceCode
        //
        //  23/10/11    新規作成
        //  24/04/22    scalar2word:"to_string"から"ostringstream"に修正
        //              桁落ちが発生する為（精度向上）。
        //     05/02    scalar2word:有効桁数が設定できる様に修正
        //-----------------------------------------------
        
        type    coded;
        
        name    couplingSource_fsi;
        libs    ("libutilityFunctionObjects.so");

        codeData
        #{
            label maxWaitTime_;
            label intervalPress_;
            label writePrecision_;
            word patchName_;
            word pressField_;
            word pointField_;
            
            //  label2word
            //    labelをwordに変換
            word label2word(label n)
            {
                char nn[10];
                sprintf(nn, "%d", n);
                return word(nn);
            }

            //  scalar2word
            //    scalarをwordに変換
            word scalar2word(scalar a)
            {
                //std::string st = std::to_string(a);
                std::ostringstream oss;
                oss.precision(writePrecision_);  //有効桁数
                oss << a;
                std::string st = oss.str();
                return word(st);
            }
            
            //  runCommand
            //    shelの実行
            void runCommand(word comm)
            {
                char ccomm[comm.size() + 1];
                strcpy(ccomm, comm.c_str());
                int err = system(ccomm);
                if (err != 0)
                {
                    FatalErrorInFunction
                        << "error: could not run command '" << comm << "' !!"
                        << abort(FatalError);
                }
            }
        #};

        //  1回のみ実行
        codeRead
        #{
        #};
        
        codeExecute
        #{
            //  runTimeを定義
            Time& runTime( const_cast<Time&>(mesh().time()) );

            //controlDictの内容読み込み
            maxWaitTime_ = readLabel
                (
                    runTime.controlDict().subDict("couplingToFistr")
                        .subDict("jobWaitingTime")
                        .lookup("maxWaitingTime")
                );
            intervalPress_ = readLabel
                (
                    runTime.controlDict().subDict("couplingToFistr")
                        .subDict("couplingInterval")
                        .lookup("pressure")
                );
            patchName_ = word
                (
                    runTime.controlDict().subDict("couplingToFistr")
                        .lookup("couplingPatch")
                );
            pressField_ = word
                (
                    runTime.controlDict().subDict("couplingToFistr")
                        .subDict("couplingField")
                        .lookup("pressField")
                );
            pointField_ = word
                (
                    runTime.controlDict().subDict("couplingToFistr")
                        .subDict("couplingField")
                        .lookup("pointField")
                );
            writePrecision_ = readLabel
                (
                    runTime.controlDict().lookup("writePrecision")
                );

            //変数の定義
            int pNo = Pstream::myProcNo();
            int np = Pstream::nProcs();
            scalar timeValue = runTime.value();
            scalar dT = runTime.deltaTValue();          //deltaT取得
            scalar beforeTime = timeValue - dT;
            label timeIdx = runTime.timeIndex();
            bool isWriteTime = runTime.writeTime();
            bool isPressCoupling = false;
            label patchId = mesh().boundaryMesh().findPatchID(patchName_);
            word procNo = label2word(pNo);              //processNo
            word nProcs = label2word(np);               //全process数
            word tVal = scalar2word(timeValue);         //現在のtime
            word btVal = scalar2word(beforeTime);       //前のtime
            word timeIndex = label2word(timeIdx);       //timeIndex
            const word dir = "coupling_FrontISTR/data/";
            const word pressFile = dir + patchName_ + "_facePress_" + tVal
                                 + "_" + procNo + "tm";
            const word dispFile = dir + patchName_ + "_disp_" + timeIndex
                                + "_" + procNo + "tm";
            word comm;

            //couplingのtimingを確認
            if ( (timeIdx % intervalPress_ == 0) or     //coupling？
                 (isWriteTime == true) )                //writeInterval？
            {
                //couplingのflagを設定
                isPressCoupling = true;
            }

            //couplingのtimingかどうか確認
            if (isPressCoupling == true)
            {
                //fieldを定義
                pointVectorField& disp = const_cast<pointVectorField&>
                    //( mesh().lookupObject<pointVectorField>("pointDisplacement") );
                    ( mesh().lookupObject<pointVectorField>(pointField_) );
                vectorField& dispVal = refCast<vectorField>
                    ( disp.boundaryFieldRef()[patchId] );
                const volScalarField& p = const_cast<volScalarField&>
                    //( mesh().lookupObject<volScalarField>("p") );
                    ( mesh().lookupObject<volScalarField>(pressField_) ); 
                const scalarField& pVal = p.boundaryField()[patchId];
                
                //========== OpenFOAM圧力とFrontISTR変位を交換する ==========
                
                //  ---- 圧力を出力 ----------------------------------
                Info << "(OF) >>> pressure value is saved to file..." << endl;
                OFstream writePress(pressFile);
                forAll (pVal, facei)
                {
                    writePress << pVal[facei] << endl;
                }
                
                //  ---------- 変位を読み込み、patchにセット ----------
                Info << "(OF) >>> waiting data of " << dispFile << "..." << endl;
                label flag = 0;
                for (int count = 0; count < maxWaitTime_; count++)
                {
                    //  file有無確認
                    IFstream readDisp (dispFile);
                    if (readDisp.good())
                    {
                        // 変位読み込み
                        Info << "(OF) >>> read and set displacement value to patch '" 
                            << patchName_ << "'..." << endl;
                        usleep(20000);      //20msのsleep
                        scalar dispx = 0.0;
                        scalar dispy = 0.0;
                        scalar dispz = 0.0;
                        forAll (dispVal, pi)
                        {
                            readDisp >> dispx >> dispy >> dispz;
                            dispVal[pi] = vector(dispx, dispy, dispz);
                        }
                        flag = 1;
                        break;
                    }
                    usleep(10000);          //10msのsleep
                    count += 1;
                }
                if (flag == 0)
                {
                    FatalErrorInFunction
                        << "error: could not read displacement!!"
                        << abort(FatalError);
                }
                
                //============ FrontISTRを裏で起動し、次の時間の変位を計算 ========
                comm  = "python3 coupling_FrontISTR/python/";
                comm += "contRun_couplingSource_fsi.py";
                comm += " " + word(tVal);       //現在のtime
                comm += " " + word(btVal);      //前のtime
                comm += " " + word(procNo);     //procNo
                comm += " " + word(nProcs);     //全proc数
                comm += " " + word(timeIndex);  //timeIndex(step数)
                comm += " &";                   //裏で起動
                Info << "(OF) >>> " << comm << endl;
                runCommand(comm);
                
                //========== OpenFOAMを再開、次の時間の圧力を計算 ==================
                //  （codedを終了し、戻る）
            }

        #};                

        codeInclude
        #{
            #include <unistd.h>
            #include "Time.H"
            #include "fvMesh.H"
            #include "volFields.H"
            #include "surfaceFields.H"
            #include "pointFields.H"
            #include "IFstream.H"
            #include "OFstream.H"
            #include "Pstream.H"
        #};

        codeOptions
        #{
            -I$(LIB_SRC)/meshTools/lnInclude \
            -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
            -I$(LIB_SRC)/transportModels/compressible/lnInclude \
            -I$(LIB_SRC)/transportModels/lnInclude
        #};
