/*---------------------------------------------------------------------------*\ ========= | \\ / 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