Debug: Database connection successful C++ C language C plus plus / Science, Technology, and Astronomy / New Mars Forums

New Mars Forums

Official discussion forum of The Mars Society and MarsNews.com

You are not logged in.

Announcement

Announcement: This forum is accepting new registrations via email. Please see Recruiting Topic for additional information. Write newmarsmember[at_symbol]gmail.com.

#1 Yesterday 08:37:13

tahanson43206
Moderator
Registered: 2018-04-27
Posts: 22,998

C++ C language C plus plus

For SpaceNut .... The C language deserves it's own topic.  It is in a class by itself.

Post #3 will show a C language program intended to compute thrust produced by an OpenFOAM model.

It was developed by ChatGPT5 (with a bit of effort), and I don't know if it is right or even close to right.

This topic is available for NewMars members to post C language programs or C++ ones.

(th)

Offline

Like button can go here

#2 Yesterday 08:38:50

tahanson43206
Moderator
Registered: 2018-04-27
Posts: 22,998

Re: C++ C language C plus plus

This post is reserved for an index to posts that may be contributed by NewMars members.

Index:
Post #3: C program for OpenFOAM to compute thrust

(th)

Offline

Like button can go here

#3 Yesterday 08:40:42

tahanson43206
Moderator
Registered: 2018-04-27
Posts: 22,998

Re: C++ C language C plus plus

This post is for thrustCalc
thrustCalc was written by ChatGPT5 (with a bit of efford) on Monday 2025/11/03

I have NO idea if the program is right or even close to right.

 
// thrustCalc.C — OpenFOAM v12-compatible, standalone thrust post-processor
// Computes force on the FLUID across a patch:
//   T = ∫_patch [ rho*(U·nHat)*U dA + (p - pAmb)*Sf ]
// Vehicle thrust = negative of this vector.

#include "argList.H"
#include "timeSelector.H"
#include "Time.H"

#include "fvMesh.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "fvc.H"

#include "IOdictionary.H"
#include "polyBoundaryMesh.H"
#include "word.H"
#include "vector.H"
#include "OFstream.H"
#include "OSspecific.H"   // mkDir

#include <fstream>
#include <iomanip>

using namespace Foam;

int main(int argc, char *argv[])
{
    // Enable time-selection flags before args are created by setRootCase.H
    timeSelector::addOptions();

    // Nice help text with --help
    argList::addNote
    (
        "Compute thrust on a patch:\n"
        "  T = ∫_patch [ rho*(U·nHat)*U dA + (p - pAmb)*Sf ]\n"
        "Force reported is on the FLUID; vehicle thrust is its negative."
    );

    #include "setRootCase.H"
    #include "createTime.H"
    instantList timeDirs = timeSelector::select0(runTime, args);
    #include "createMesh.H"

    // Read settings from system/thrustCalcDict
    IOdictionary dict
    (
        IOobject
        (
            "thrustCalcDict",
            runTime.system(),
            runTime,
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    );

    word patchName("outlet");
    dict.readIfPresent("patch", patchName);

    word inletName("");                 // leave absent to ignore
    dict.readIfPresent("inletPatch", inletName);

    scalar pAmb(0.0);
    dict.readIfPresent("pAmb", pAmb);

    // Output path
    fileName outDir = runTime.path()/"postProcessing"/"thrustCalc"/patchName;
    mkDir(outDir);
    const fileName outFile = outDir/"thrust.dat";

    // Helper: find patch index by name (v12-safe)
    auto findPatch = [&](const word& name) -> label
    {
        if (!name.size()) return -1;
        const fvBoundaryMesh& bnd = mesh.boundary();
        forAll(bnd, i)
        {
            if (bnd[i].name() == name) return i;
        }
        return -1;
    };

    forAll(timeDirs, ti)
    {
        runTime.setTime(timeDirs[ti], ti);
        mesh.readUpdate();

        // Exact time directory name (no rounding)
        const word curTName = timeDirs[ti].name();

        // Read fields at this time
        volVectorField U
        (
            IOobject("U",   curTName, mesh, IOobject::MUST_READ, IOobject::NO_WRITE),
            mesh
        );
        volScalarField p
        (
            IOobject("p",   curTName, mesh, IOobject::MUST_READ, IOobject::NO_WRITE),
            mesh
        );
        volScalarField rho
        (
            IOobject("rho", curTName, mesh, IOobject::MUST_READ, IOobject::NO_WRITE),
            mesh
        );

        // Compute contribution on a patch (fields are in scope here)
        auto computePatch = [&](const word& name, bool subtract) -> vector
        {
            if (!name.size()) return vector::zero;   // silent ignore

            vector result(vector::zero);
            const label pid = findPatch(name);
            if (pid < 0)
            {
                Info<< "thrustCalc: patch '"<< name <<"' not found (skipping)." << nl;
                return result;
            }

            const vectorField& Sf = mesh.Sf().boundaryField()[pid];
            const fvPatchVectorField& Ub = U.boundaryField()[pid];
            const fvPatchScalarField& pb = p.boundaryField()[pid];
            const fvPatchScalarField& rb = rho.boundaryField()[pid];

            const label N = Sf.size();
            for (label i=0; i<N; ++i)
            {
                const scalar magSf = mag(Sf[i]);
                const vector nHat  = (magSf > VSMALL ? Sf[i]/magSf : vector::zero);

                const scalar Un = (Ub[i] & nHat);
                const vector mom   = rb[i]*Un*Ub[i]*magSf;   // rho * Un * U * dA
                const vector pTerm = (pb[i] - pAmb)*Sf[i];   // (p - pAmb) * Sf

                result += (mom + pTerm);
            }
            return subtract ? -result : result;
        };

        const vector thrust = computePatch(patchName, /*subtract*/false)
                            + computePatch(inletName, /*subtract*/true);

        const scalar t    = runTime.value();
        const scalar Fmag = mag(thrust);

        // Decide if we need a header (file does not exist or empty)
        bool needHeader = true;
        {
            std::ifstream chk(outFile.c_str());
            needHeader = !chk.good() || (chk.peek() == std::ifstream::traits_type::eof());
        }

        // Append one row (with header if needed)
        std::ofstream os(outFile.c_str(), std::ios_base::app);
        if (needHeader)
        {
            os << "# timeDir        t[s]           Fx[N]           Fy[N]           Fz[N]           |F|[N]\n";
        }
        os.setf(std::ios_base::scientific);
        os << curTName << " "
           << std::setprecision(10) << t << " "
           << thrust.x() << " " << thrust.y() << " " << thrust.z() << " "
           << Fmag << "\n";
        os.close();

        Info<< "thrustCalc: t="<< t
            << "  Thrust_on_fluid [N] = " << thrust
            << "  |F|=" << Fmag
            << "   (vehicle reaction = -value above)" << nl;
    }

    Info<< "thrustCalc: wrote " << outFile << nl;
    return 0;
}

See the OpenFOAM topic for output of the program and related discussion.

When I say "with some effort" I am commenting upon the struggle that I observed as ChatGPT5 was attempting to create this program. As I watched the process unfold, I noted that OpenFOAM has multiple versions and the resources ChatGPT5 consults include human generated data which is (apparently) often misleading or wrong, or out of date, or otherwise difficult to work with.

On top of that, the problem to be solved is (from my perspective) extremely complex.  The status of many thousands of cells is preserved in each time record. Time records are recorded every .05 seconds of simulation time, so we have five time directories for each 1/4 second of run time.

(th)

Offline

Like button can go here

Board footer

Powered by FluxBB