/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2007-2023 PCOpt/NTUA
Copyright (C) 2013-2023 FOSS GP
Copyright (C) 2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see .
\*---------------------------------------------------------------------------*/
#include "volBSplinesBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
defineTypeNameAndDebug(volBSplinesBase, 0);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
volBSplinesBase::volBSplinesBase
(
const fvMesh& mesh
)
:
MeshObject_type(mesh),
volume_(0),
activeDesignVariables_(0)
{
const dictionary NURBSdict
(
IOdictionary
(
IOobject
(
"dynamicMeshDict",
mesh.time().constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
)
).subDict("volumetricBSplinesMotionSolverCoeffs")
);
// Populate NURBS volumes
volume_.resize(NURBSdict.size());
label iBox(0);
for (const entry& dEntry : NURBSdict)
{
if (dEntry.isDict())
{
volume_.set
(
iBox,
NURBS3DVolume::New(dEntry.dict(), mesh, true)
);
volume_[iBox].writeParamCoordinates();
iBox++;
}
}
volume_.resize(iBox);
// Determine active design variables
activeDesignVariables_.setSize(3*getTotalControlPointsNumber(), -1);
label iActive(0);
const labelList startCpID(getStartCpID());
forAll(volume_, boxI)
{
const label start(3*startCpID[boxI]);
const boolList& isActiveVar = volume_[boxI].getActiveDesignVariables();
forAll(isActiveVar, varI)
{
if (isActiveVar[varI])
{
activeDesignVariables_[iActive++] = start + varI;
}
}
}
activeDesignVariables_.setSize(iActive);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const PtrList& volBSplinesBase::boxes() const
{
return volume_;
}
PtrList& volBSplinesBase::boxesRef()
{
return volume_;
}
const NURBS3DVolume& volBSplinesBase::box(const label boxI) const
{
return volume_[boxI];
}
NURBS3DVolume& volBSplinesBase::boxRef(const label boxI)
{
return volume_[boxI];
}
const vectorField& volBSplinesBase::getControlPoints(const label& iNURB) const
{
return volume_[iNURB].getControlPoints();
}
vectorField volBSplinesBase::getAllControlPoints() const
{
DynamicList totalCPs(0);
forAll(volume_, iNURB)
{
totalCPs.push_back(volume_[iNURB].getControlPoints());
}
return vectorField(std::move(totalCPs));
}
Foam::label Foam::volBSplinesBase::getTotalControlPointsNumber() const
{
label nCPs(0);
forAll(volume_, iNURB)
{
nCPs += volume_[iNURB].getControlPoints().size();
}
return nCPs;
}
label Foam::volBSplinesBase::getNumberOfBoxes() const
{
return volume_.size();
}
labelList volBSplinesBase::getStartCpID() const
{
// Allocate an extra entry to track in which box a CP might be
labelList startID(getNumberOfBoxes() + 1);
startID[0] = 0;
forAll(volume_, iNURB)
{
startID[iNURB+1] =
startID[iNURB] + volume_[iNURB].getControlPoints().size();
}
return startID;
}
labelList volBSplinesBase::getStartVarID() const
{
return 3*getStartCpID();
}
label volBSplinesBase::findBoxID(const label cpI) const
{
const labelList startCPID(getStartCpID());
for (label iBox = 0; iBox < startCPID.size() - 1 ; ++iBox)
{
if (cpI >= startCPID[iBox] || cpI < startCPID[iBox + 1])
{
return iBox;
}
}
FatalErrorInFunction
<< "Invalid control point ID " << cpI << endl
<< exit(FatalError);
return -1;
}
Vector