MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
RigidBodies< nDim > Class Template Reference

#include <rigidbodies.h>

Inheritance diagram for RigidBodies< nDim >:
[legend]
Collaboration diagram for RigidBodies< nDim >:
[legend]

Classes

struct  Shapes
 
struct  Timers
 

Public Types

using CartesianSolver = typename maia::CartesianSolver< nDim, RigidBodies >
 
using Cell = typename maia::grid::tree::Tree< nDim >::Cell
 
using Geom = Geometry< nDim >
 
using Grid = typename CartesianSolver::Grid
 
using GridProxy = typename CartesianSolver::GridProxy
 
using Status = maia::rb::collector::Status
 
- Public Types inherited from maia::CartesianSolver< nDim, RigidBodies< nDim > >
using Grid = CartesianGrid< nDim >
 
using GridProxy = typename maia::grid::Proxy< nDim >
 
using Geom = Geometry< nDim >
 
using TreeProxy = maia::grid::tree::TreeProxy< nDim >
 
using Cell = maia::grid::tree::Cell
 

Public Member Functions

Geomgeometry () const
 Access the solver's geometry. More...
 
void preTimeStep () override
 Resetting the 2-Step predictor-corrector cycle. More...
 
MBool solutionStep () override
 
void postTimeStep ()
 
void initSolver () override
 
void finalizeInitSolver () override
 
void saveSolverSolution (const MBool, const MBool)
 
void cleanUp ()
 
MFloat time () const override
 Return the time. More...
 
MInt noInternalCells () const override
 Return the number of internal cells within this solver. More...
 
MBool prepareRestart (MBool writeRestart, MBool &) override
 Prepare the solvers for a grid-restart. More...
 
void reIntAfterRestart (MBool) override
 
void writeRestartFile (const MBool writeRestart, const MBool writeBackup, const MString, MInt *) override
 Write restart file for the RigidBody solver. More...
 
MInt a_hasNeighbor (const MInt, const MInt) const
 
MPI_Comm mpiComm () const
 
void prepareAdaptation (std::vector< std::vector< MFloat > > &NotUsed(sensors), std::vector< MFloat > &NotUsed(sensorWeight), std::vector< std::bitset< 64 > > &NotUsed(sensorCellFlag), std::vector< MInt > &NotUsed(sensorSolverId)) override
 
void prepareAdaptation () override
 prepare adaptation for split adaptation before the adaptation loop More...
 
void setSensors (std::vector< std::vector< MFloat > > &, std::vector< MFloat > &, std::vector< std::bitset< 64 > > &, std::vector< MInt > &) override
 set solver sensors for split adaptation within the adaptation loop More...
 
void resizeGridMap ()
 Swap the given cells. More...
 
void postAdaptation () override
 post adaptation for split adaptation within the adaptation loop More...
 
void finalizeAdaptation () override
 finalize adaptation for split sadptation after the adaptation loop More...
 
void removeChilds (const MInt) override
 Coarsen the given cell. More...
 
void reinitAfterAdaptation () override
 
void refineCell (const MInt) override
 Refine the given cell. More...
 
void swapCells (const MInt, const MInt) override
 Swap the given cells. More...
 
void swapProxy (const MInt cellId0, const MInt cellId1)
 Swap the given cells. More...
 
void setCellWeights (MFloat *) override
 Set cell weights. More...
 
 RigidBodies (const MInt solverId, GridProxy &gridProxy, Geom &geometry, MPI_Comm comm)
 C'tor for the RigidBodies solver. More...
 
 ~RigidBodies ()
 D'tor for the RigidBodies solver. More...
 
void initBodyLog ()
 Initalize log-file. More...
 
void logBodyData ()
 Writing a simple log file containing the current state for all bodies. More...
 
void printScalingVariables ()
 
void totalKineticEnergy ()
 
void computeBodies ()
 Calculates the new state for all bodies. More...
 
void correctBodies ()
 Correcting the state of all bodies using all available external forces/fluxes. More...
 
void checkDummyBodiesForSwap ()
 
void updateConnections ()
 
void exchangeKinematicData ()
 exchange of predictor & corrector step output More...
 
void exchangeFsiData ()
 exchange of summed forces and torques More...
 
void boxSeedInitialize ()
 
void linSpace (MFloat start, MFloat end, MInt num, std::vector< MFloat > &linspaced)
 
void computeBodyPropertiesForced (MInt returnMode, MFloat *bodyData, MInt bodyId, MFloat time)
 
void initGridProperties ()
 
void updateInfoDiameter (const MBool initCall=false)
 
void updateMaxLevel (MInt newMaxLevel)
 
void findLocalBodies ()
 searches in all initial Bodies for local bodies More...
 
void findTransferBodies ()
 creates list with all edge bodies that are no longer contained within local domain More...
 
void updateBodyDomainConnections (MBool initCall)
 updates local/ edge body domain connections More...
 
void createDummyBody (MInt bodyId)
 appends new DummyBody to collector More...
 
void exchangeEdgeBodyData ()
 exchanges relevant body connections with new neighbor domains More...
 
void initRemoteDummyBodyData (const MInt bodyId)
 initalize kinematic data of dummyBody that is associated with a remoteBody More...
 
void exchangeNeighborConnectionInfo ()
 
void exchangeTransferBodies ()
 exchanges transfer bodies More...
 
void exchangeNeighborNeighborRemote (std::vector< std::vector< MInt > > &bodyIdsForRemoteDomain, std::vector< std::vector< MInt > > &homeDomainIdsForRemoteDomain, std::map< MInt, std::vector< MInt > > &tmpRemoteMap)
 
void exchangeNeighborNeighborHome (std::vector< std::vector< MInt > > &bodyIdsForHomeDomain, std::vector< std::vector< MInt > > &remoteDomainIdsForHomeDomain, std::vector< std::vector< std::array< MFloat, nDim > > > &shiftForHomeDomain)
 
MFloat calculatePeriodicShift (MInt intersectingCellId, MInt direction)
 periodic shift for position for further data exchange More...
 
void exchangeBufferLengthsNeighbor (std::vector< MInt > &noToRecv, std::vector< std::vector< MInt > > &bodyList)
 exchange of Buffer legnths for further exchanges More...
 
void exchangeBufferLengthsNeighbor (std::vector< MInt > &noToRecv, std::map< MInt, std::vector< MInt > > &bodyList)
 exchange of Buffer legnths for further exchanges More...
 
void exchangeBufferLengthsAllToRoot (std::vector< MInt > &noToRecv, const MInt noToSend)
 exchange of Buffer lengths all to root More...
 
void exchangeBufferLengthsAllToAll (std::vector< MInt > &noToRecv, const MInt noToSend)
 exchange of Buffer lengths all to all More...
 
void exchangeBufferLengthsNeighbors (std::vector< MInt > &noToRecv, const MInt noToSend)
 exchange of Buffer lengths all to all in direct neighborhood More...
 
void exchangeBufferLengthsRemoteToHome (std::vector< MInt > &noToRecv, std::vector< MInt > &noToSend)
 
void exchangeBodyVariablesAllToAll ()
 exchange of Body Variables all to all More...
 
MLong getDomainOffset ()
 for new restartFile format More...
 
void printBodyDomainConnections ()
 debugging: print all necessary mappings for each partition in specific file More...
 
template<MInt bodyType>
MFloat getDistance (const MFloat *const coordinates, const MInt bodyId)
 Calculates the closest distance between a given point and body. More...
 
MFloat getDistanceSphere (const MFloat *coordinates, const MInt bodyId)
 Calculates the closest distance between a given point and a sphere. More...
 
MFloat getDistancePiston (const MFloat *coordinates, const MInt bodyId)
 Calculates the closest distance between a given point and a piston. More...
 
MFloat getDistanceCube (const MFloat *coordinates, const MInt bodyId)
 Calculates the closest distance between a given point and a cube. More...
 
MFloat getDistanceEllipsoid (const MFloat *coordinates, const MInt bodyId)
 Calculates the closest distance between a given point and a ellipsoid. More...
 
MInt size () const
 
MInt getLocalBodyId (MInt globalBodyId)
 
MInt getGlobalBodyId (MInt localBodyId)
 
MBool isLocalBody (MInt bodyId)
 
MBool isRemoteBody (MInt bodyId)
 
MInt noEmbeddedBodies () const
 
MInt noConnectingBodies () const
 
MInt noCollectorBodies () const
 
MInt noHomeDomains () const
 
MInt noRemoteDomains () const
 
MBool hasAssociatedDummyBody (const MInt bodyId) const
 
void addForce (const MInt bodyId, const std::array< MFloat, nDim > &force)
 
void addTorque (const MInt bodyId, const std::array< MFloat, nRot > &torque)
 
void resetForce ()
 
void resetTorque ()
 
MFloat a_bodyMass (const MInt bodyId)
 
MFloat a_volume (const MInt bodyId)
 
MFloata_bodyRadii (const MInt bodyId, const MInt n)
 
MFloata_bodyRadius (const MInt bodyId)
 
void getVelocity (const MInt bodyId, std::array< MFloat, nDim > &velocity)
 
void incrementHeatFlux (const MInt bodyId, MFloat heatflux)
 
MFloat getHeatFlux (const MInt bodyId)
 
MFloata_bodyForce (const MInt bodyId)
 
MFloata_bodyForce (const MInt bodyId, const MInt dim)
 
MFloat a_bodyForce (const MInt bodyId, const MInt dim) const
 
MFloata_bodyCenter (const MInt bodyId, const MInt dim)
 
MFloat a_bodyCenter (const MInt bodyId, const MInt dim) const
 
MFloata_bodyCenterOld (const MInt bodyId, const MInt dim)
 
MFloat a_bodyCenterOld (const MInt bodyId, const MInt dim) const
 
MFloata_bodyVelocity (const MInt bodyId, const MInt dim)
 
MFloat a_bodyVelocity (const MInt bodyId, const MInt dim) const
 
MFloata_bodyVelocityOld (const MInt bodyId, const MInt dim)
 
MFloat a_bodyVelocityOld (const MInt bodyId, const MInt dim) const
 
MFloata_bodyAcceleration (const MInt bodyId, const MInt dim)
 
MFloat a_bodyAcceleration (const MInt bodyId, const MInt dim) const
 
MFloata_bodyAccelerationOld (const MInt bodyId, const MInt dim)
 
MFloat a_bodyAccelerationOld (const MInt bodyId, const MInt dim) const
 
MFloata_bodyTemperature (const MInt bodyId)
 
MFloat a_bodyTemperature (const MInt bodyId) const
 
MFloata_bodyTemperatureOld (const MInt bodyId)
 
MFloat a_bodyTemperatureOld (const MInt bodyId) const
 
MFloata_bodyHeatFlux (const MInt bodyId)
 
MFloat a_bodyHeatFlux (const MInt bodyId) const
 
MFloata_bodyDensityRatio (const MInt bodyId)
 
MFloat a_bodyDensityRatio (const MInt bodyId) const
 
MFloata_bodyInertia (const MInt bodyId, const MInt dim)
 
MFloat a_bodyInertia (const MInt bodyId, const MInt dim) const
 
MFloata_bodyQuaternionT1 (const MInt bodyId, const MInt dim)
 
MFloat a_bodyQuaternionT1 (const MInt bodyId, const MInt dim) const
 
MFloata_bodyQuaternionT1B2 (const MInt bodyId, const MInt dim)
 
MFloat a_bodyQuaternionT1B2 (const MInt bodyId, const MInt dim) const
 
MFloata_angularVelocityT1 (const MInt bodyId, const MInt dim)
 
MFloat a_angularVelocityT1 (const MInt bodyId, const MInt dim) const
 
MFloata_angularVelocityT1B2 (const MInt bodyId, const MInt dim)
 
MFloat a_angularVelocityT1B2 (const MInt bodyId, const MInt dim) const
 
MFloata_angularVelocityBodyT1 (const MInt bodyId, const MInt dim)
 
MFloat a_angularVelocityBodyT1 (const MInt bodyId, const MInt dim) const
 
MFloata_angularVelocityBodyT1B2 (const MInt bodyId, const MInt dim)
 
MFloat a_angularVelocityBodyT1B2 (const MInt bodyId, const MInt dim) const
 
MFloata_angularAccelerationT1 (const MInt bodyId, const MInt dim)
 
MFloat a_angularAccelerationT1 (const MInt bodyId, const MInt dim) const
 
MFloata_angularAccelerationBody (const MInt bodyId, const MInt dim)
 
MFloat a_angularAccelerationBody (const MInt bodyId, const MInt dim) const
 
MFloata_torqueT1 (const MInt bodyId, const MInt dim)
 
MFloat a_torqueT1 (const MInt bodyId, const MInt dim) const
 
Statusa_status (const MInt bodyId)
 
Status a_status (const MInt bodyId) const
 
MFloata_bodyTorque (const MInt bodyId)
 
MFloata_bodyTorque (const MInt bodyId, const MInt dim)
 
MFloat a_bodyTorque (const MInt bodyId, const MInt dim) const
 
MFloata_angularVelocity (const MInt bodyId, const MInt dim)
 
MFloat a_angularVelocity (const MInt bodyId, const MInt dim) const
 
MFloata_angularVelocityBody (const MInt bodyId, const MInt dim)
 
MFloat a_angularVelocityBody (const MInt bodyId, const MInt dim) const
 
void getAngularVelocity (const MInt bodyId, std::array< MFloat, nRot > &angularVelocity)
 
MFloat a_bodyVelocityMag (const MInt bodyId)
 
MFloatgetBodyProperties (MInt returnMode, MInt bodyId)
 
MInt a_bodyType () const
 
void setTimestep (const MFloat timestep)
 
void saveBodyRestartFile (const MBool backup)
 Write restart file for the RigidBody solver. More...
 
void loadBodyRestartFile ()
 Loads restart file for the RigidBodies solver. More...
 
void loadBodiesSizeAndPosition ()
 loadind no of embedded bodies and it's position from restart file More...
 
MInt a_noCells () const
 
- Public Member Functions inherited from maia::CartesianSolver< nDim, RigidBodies< nDim > >
 CartesianSolver (const MInt solverId, GridProxy &gridProxy_, const MPI_Comm comm, const MBool checkActive=false)
 
MInt minLevel () const
 Read-only accessors for grid data. More...
 
MInt maxLevel () const
 
MInt maxNoGridCells () const
 
MInt maxRefinementLevel () const
 
MInt maxUniformRefinementLevel () const
 
MInt noNeighborDomains () const
 
MInt neighborDomain (const MInt id) const
 
MLong domainOffset (const MInt id) const
 
MInt noHaloLayers () const
 
MInt noHaloCells (const MInt domainId) const
 
MInt haloCellId (const MInt domainId, const MInt cellId) const
 
MInt noWindowCells (const MInt domainId) const
 
MInt windowCellId (const MInt domainId, const MInt cellId) const
 
MString gridInputFileName () const
 
MFloat reductionFactor () const
 
MFloat centerOfGravity (const MInt dir) const
 
MInt neighborList (const MInt cellId, const MInt dir) const
 
const MLonglocalPartitionCellGlobalIds (const MInt cellId) const
 
MLong localPartitionCellOffsets (const MInt index) const
 
MInt noMinCells () const
 
MInt minCell (const MInt id) const
 
const MInthaloCell (const MInt domainId, const MInt cellId) const
 
const MIntwindowCell (const MInt domainId, const MInt cellId) const
 
MBool isActive () const override
 
constexpr GridProxygrid () const
 
GridProxygrid ()
 
virtual void sensorDerivative (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorDivergence (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorTotalPressure (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorEntropyGrad (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorEntropyQuot (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorVorticity (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorInterface (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
void sensorLimit (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt, std::function< MFloat(MInt)>, const MFloat, const MInt *, const MBool, const MBool allowCoarsening=true)
 simple sensor to apply a limit for a value More...
 
void sensorSmooth (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 sensor to smooth level jumps NOTE: only refines additional cells to ensure a smooth level transition this requires that all other sensors are frozen i.e. no refine/coarse sensors set! More...
 
void sensorBand (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 This sensor generates a max refinement band around the cells with max refinement level. In order for it to work, the property addedAdaptationSteps has to be equal to /maxRefinementLevel() - minLevel()/. This sensor also ensures a smooth transition between levels. Do not use together with sensorSmooth. More...
 
virtual void sensorMeanStress (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorParticle (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorSpecies (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorPatch (std::vector< std::vector< MFloat > > &sensor, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)
 
virtual void sensorCutOff (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
void saveSensorData (const std::vector< std::vector< MFloat > > &sensors, const MInt &level, const MString &gridFileName, const MInt *const recalcIds) override
 Saves all sensor values for debug/tunig purposes. More...
 
void assertValidGridCellId (const MInt) const
 
MLong c_parentId (const MInt cellId) const
 Returns the grid parent id of the cell cellId. More...
 
MLong c_neighborId (const MInt cellId, const MInt dir) const
 Returns the grid neighbor id of the grid cell cellId dir. More...
 
MInt c_noCells () const
 
MInt c_level (const MInt cellId) const
 
MLong c_globalGridId (const MInt cellId)
 
void exchangeData (T *data, const MInt dataBlockSize=1)
 Exchange memory in 'data' assuming a solver size of 'dataBlockSize' per cell. More...
 
void exchangeLeafData (std::function< T &(MInt, MInt)> data, const MInt noDat=1)
 Blocking exchange memory in 'data' assuming a solver size of 'dataBlockSize' per cell NOTE: exchange is only performed on leaf-cells and leaf-NeighborDomains Assumes, that updateLeafCellExchange has been called in the proxy previously! More...
 
void exchangeSparseLeafValues (G getData, S setData, const MInt dataSize, M cellMapping)
 Exchange of sparse data structures on max Level. More...
 
void exchangeAzimuthalPer (T *data, MInt dataBlockSize=1, MInt firstBlock=0)
 Exchange of sparse data structures on max Level. More...
 
void collectVariables (T *variablesIn, ScratchSpace< T > &variablesOut, const std::vector< MString > &variablesNameIn, std::vector< MString > &variablesNameOut, const MInt noVars, const MInt noCells, const MBool reverseOrder=false)
 generalised helper function for writing restart files! This is necessary for example if the minLevel shall be raised at the new restart! More...
 
void collectVariables (T **variablesIn, ScratchSpace< T > &variablesOut, const std::vector< MString > &variablesNameIn, std::vector< MString > &variablesNameOut, const MInt noVars, const MInt noCells)
 generalised helper function for writing restart files! This is necessary for example if the minLevel shall be raised at the new restart! More...
 
void saveGridFlowVars (const MChar *fileName, const MChar *gridFileName, const MInt noTotalCells, const MInt noInternal, MFloatScratchSpace &dbVariables, std::vector< MString > &dbVariablesName, MInt noDbVars, MIntScratchSpace &idVariables, std::vector< MString > &idVariablesName, MInt noIdVars, MFloatScratchSpace &dbParameters, std::vector< MString > &dbParametersName, MIntScratchSpace &idParameters, std::vector< MString > &idParametersName, MInt *recalcIds, MFloat time)
 This function writes the parallel Netcdf cartesian grid cell based solution/restart file currently used in PostData, LPT and LS solvers! More...
 
void collectParameters (T, ScratchSpace< T > &, const MChar *, std::vector< MString > &)
 This function collects a single parameters for the massivley parallel IO functions. More...
 
void calcRecalcCellIdsSolver (const MInt *const recalcIdsTree, MInt &noCells, MInt &noInternalCellIds, std::vector< MInt > &recalcCellIdsSolver, std::vector< MInt > &reorderedCellIds)
 Derive recalc cell ids of the solver and reordered cell ids. More...
 
- Public Member Functions inherited from Solver
MString getIdentifier (const MBool useSolverId=false, const MString preString="", const MString postString="_")
 
virtual ~Solver ()=default
 
virtual MInt noInternalCells () const =0
 Return the number of internal cells within this solver. More...
 
virtual MFloat time () const =0
 Return the time. More...
 
virtual MInt noVariables () const
 Return the number of variables. More...
 
virtual void getDimensionalizationParams (std::vector< std::pair< MFloat, MString > > &) const
 Return the dimensionalization parameters of this solver. More...
 
void updateDomainInfo (const MInt domainId, const MInt noDomains, const MPI_Comm mpiComm, const MString &loc)
 Set new domain information. More...
 
virtual MFloata_slope (const MInt, MInt const, const MInt)
 
virtual MBool a_isBndryCell (const MInt) const
 
virtual MFloata_FcellVolume (MInt)
 
virtual MInt getCurrentTimeStep () const
 
virtual void accessSampleVariables (MInt, MFloat *&)
 
virtual void getSampleVariableNames (std::vector< MString > &NotUsed(varNames))
 
virtual MBool a_isBndryGhostCell (MInt) const
 
virtual void saveCoarseSolution ()
 
virtual void getSolverSamplingProperties (std::vector< MInt > &NotUsed(samplingVarIds), std::vector< MInt > &NotUsed(noSamplingVars), std::vector< std::vector< MString > > &NotUsed(samplingVarNames), const MString NotUsed(featureName)="")
 
virtual void initSolverSamplingVariables (const std::vector< MInt > &NotUsed(varIds), const std::vector< MInt > &NotUsed(noSamplingVars))
 
virtual void calcSamplingVariables (const std::vector< MInt > &NotUsed(varIds), const MBool NotUsed(exchange))
 
virtual void calcSamplingVarAtPoint (const MFloat *NotUsed(point), const MInt NotUsed(id), const MInt NotUsed(sampleVarId), MFloat *NotUsed(state), const MBool NotUsed(interpolate)=false)
 
virtual void balance (const MInt *const NotUsed(noCellsToReceiveByDomain), const MInt *const NotUsed(noCellsToSendByDomain), const MInt *const NotUsed(targetDomainsByCell), const MInt NotUsed(oldNoCells))
 Perform load balancing. More...
 
virtual MBool hasSplitBalancing () const
 Return if load balancing for solver is split into multiple methods or implemented in balance() More...
 
virtual void balancePre ()
 
virtual void balancePost ()
 
virtual void finalizeBalance ()
 
virtual void resetSolver ()
 Reset the solver/solver for load balancing. More...
 
virtual void cancelMpiRequests ()
 Cancel open mpi (receive) requests in the solver (e.g. due to interleaved execution) More...
 
virtual void setCellWeights (MFloat *)
 Set cell weights. More...
 
virtual MInt noLoadTypes () const
 
virtual void getDefaultWeights (MFloat *NotUsed(weights), std::vector< MString > &NotUsed(names)) const
 
virtual void getLoadQuantities (MInt *const NotUsed(loadQuantities)) const
 
virtual MFloat getCellLoad (const MInt NotUsed(cellId), const MFloat *const NotUsed(weights)) const
 
virtual void limitWeights (MFloat *NotUsed(weights))
 
virtual void localToGlobalIds ()
 
virtual void globalToLocalIds ()
 
virtual MInt noCellDataDlb () const
 Methods to inquire solver data information. More...
 
virtual MInt cellDataTypeDlb (const MInt NotUsed(dataId)) const
 
virtual MInt cellDataSizeDlb (const MInt NotUsed(dataId), const MInt NotUsed(cellId))
 
virtual void getCellDataDlb (const MInt NotUsed(dataId), const MInt NotUsed(oldNoCells), const MInt *const NotUsed(bufferIdToCellId), MInt *const NotUsed(data))
 
virtual void getCellDataDlb (const MInt NotUsed(dataId), const MInt NotUsed(oldNoCells), const MInt *const NotUsed(bufferIdToCellId), MLong *const NotUsed(data))
 
virtual void getCellDataDlb (const MInt NotUsed(dataId), const MInt NotUsed(oldNoCells), const MInt *const NotUsed(bufferIdToCellId), MFloat *const NotUsed(data))
 
virtual void setCellDataDlb (const MInt NotUsed(dataId), const MInt *const NotUsed(data))
 
virtual void setCellDataDlb (const MInt NotUsed(dataId), const MLong *const NotUsed(data))
 
virtual void setCellDataDlb (const MInt NotUsed(dataId), const MFloat *const NotUsed(data))
 
virtual void getGlobalSolverVars (std::vector< MFloat > &NotUsed(globalFloatVars), std::vector< MInt > &NotUsed(globalIntVars))
 
virtual void setGlobalSolverVars (std::vector< MFloat > &NotUsed(globalFloatVars), std::vector< MInt > &NotUsed(globalIdVars))
 
void enableDlbTimers ()
 
void reEnableDlbTimers ()
 
void disableDlbTimers ()
 
MBool dlbTimersEnabled ()
 
void startLoadTimer (const MString name)
 
void stopLoadTimer (const MString &name)
 
void stopIdleTimer (const MString &name)
 
void startIdleTimer (const MString &name)
 
MBool isLoadTimerRunning ()
 
virtual MInt noSolverTimers (const MBool NotUsed(allTimings))
 
virtual void getSolverTimings (std::vector< std::pair< MString, MFloat > > &NotUsed(solverTimings), const MBool NotUsed(allTimings))
 
virtual void getDomainDecompositionInformation (std::vector< std::pair< MString, MInt > > &NotUsed(domainInfo))
 
void setDlbTimer (const MInt timerId)
 
virtual void prepareAdaptation (std::vector< std::vector< MFloat > > &, std::vector< MFloat > &, std::vector< std::bitset< 64 > > &, std::vector< MInt > &)
 
virtual void reinitAfterAdaptation ()
 
virtual void prepareAdaptation ()
 prepare adaptation for split adaptation before the adaptation loop More...
 
virtual void setSensors (std::vector< std::vector< MFloat > > &, std::vector< MFloat > &, std::vector< std::bitset< 64 > > &, std::vector< MInt > &)
 set solver sensors for split adaptation within the adaptation loop More...
 
virtual void saveSensorData (const std::vector< std::vector< MFloat > > &, const MInt &, const MString &, const MInt *const)
 
virtual void postAdaptation ()
 post adaptation for split adaptation within the adaptation loop More...
 
virtual void finalizeAdaptation ()
 finalize adaptation for split sadptation after the adaptation loop More...
 
virtual void refineCell (const MInt)
 Refine the given cell. More...
 
virtual void removeChilds (const MInt)
 Coarsen the given cell. More...
 
virtual void removeCell (const MInt)
 Remove the given cell. More...
 
virtual void swapCells (const MInt, const MInt)
 Swap the given cells. More...
 
virtual void swapProxy (const MInt, const MInt)
 Swap the given cells. More...
 
virtual MInt cellOutside (const MFloat *, const MInt, const MInt)
 Check whether cell is outside the fluid domain. More...
 
virtual void resizeGridMap ()
 Swap the given cells. More...
 
virtual MBool prepareRestart (MBool, MBool &)
 Prepare the solvers for a grid-restart. More...
 
virtual void reIntAfterRestart (MBool)
 
MPI_Comm mpiComm () const
 Return the MPI communicator used by this solver. More...
 
virtual MInt domainId () const
 Return the domainId (rank) More...
 
virtual MInt noDomains () const
 
virtual MBool isActive () const
 
void setSolverStatus (const MBool status)
 
MBool getSolverStatus ()
 Get the solver status indicating if the solver is currently active in the execution recipe. More...
 
MString testcaseDir () const
 Return the testcase directory. More...
 
MString outputDir () const
 Return the directory for output files. More...
 
MString restartDir () const
 Return the directory for restart files. More...
 
MString solverMethod () const
 Return the solverMethod of this solver. More...
 
MString solverType () const
 Return the solverType of this solver. More...
 
MInt restartInterval () const
 Return the restart interval of this solver. More...
 
MInt restartTimeStep () const
 Return the restart interval of this solver. More...
 
MInt solverId () const
 Return the solverId. More...
 
MBool restartFile ()
 
MInt readSolverSamplingVarNames (std::vector< MString > &varNames, const MString featureName="") const
 Read sampling variables names, store in vector and return the number of sampling variables. More...
 
virtual MBool hasRestartTimeStep () const
 
virtual MBool forceAdaptation ()
 
virtual void preTimeStep ()=0
 
virtual void postTimeStep ()=0
 
virtual void initSolver ()=0
 
virtual void finalizeInitSolver ()=0
 
virtual void saveSolverSolution (const MBool NotUsed(forceOutput)=false, const MBool NotUsed(finalTimeStep)=false)=0
 
virtual void cleanUp ()=0
 
virtual MBool solutionStep ()
 
virtual void preSolutionStep (MInt)
 
virtual MBool postSolutionStep ()
 
virtual MBool solverConverged ()
 
virtual void getInterpolatedVariables (MInt, const MFloat *, MFloat *)
 
virtual void loadRestartFile ()
 
virtual MInt determineRestartTimeStep () const
 
virtual void writeRestartFile (MBool)
 
virtual void writeRestartFile (const MBool, const MBool, const MString, MInt *)
 
virtual void setTimeStep ()
 
virtual void implicitTimeStep ()
 
virtual void prepareNextTimeStep ()
 

Public Attributes

Geomm_geometry
 
std::array< MFloat, 2 > m_distFac {}
 
MFloat m_infoDiameter {}
 
MInt m_maxSensorLevel {}
 
MInt m_currMaxLevel {}
 
MBool m_printKineticEnergy = false
 
MBool m_logBodyData = false
 
MBool m_bodyWasDeleted = false
 
MInt m_intervalBodyLog = 1
 
std::ofstream m_log
 
std::ofstream m_anglog
 
std::ofstream m_debugFileStream
 
- Public Attributes inherited from Solver
std::set< MIntm_freeIndices
 
MBool m_singleAdaptation = false
 
MBool m_splitAdaptation = true
 
MBool m_saveSensorData = false
 

Private Member Functions

void predictorStep ()
 Peform a prediction for all bodies. More...
 
void correctorStep ()
 Correct the state of all bodies using external forces/fluxes/torques. More...
 
void advanceBodies ()
 Copy the body data for time t to t-1 to prepare the next timestep. More...
 
void predictRotation (const MInt bodyId)
 
void correctRotation (const MInt bodyId)
 
void transformToWorldFrame (const MFloat *const quaternion, const MFloat *const vectorBody, MFloat *const vectorWorld)
 Transform a vector form the body frame to the world frame. More...
 
void transformToBodyFrame (const MFloat *const quaternion, const MFloat *const vectorWorld, MFloat *const vectorBody)
 Transform a vector form the world frame to the body frame. More...
 
void transformToBodyFrame (const MFloat *const quaternion, MFloat *const vecInOut)
 Transform a vector form the world frame to the body frame. More...
 
void advanceQuaternion (const MFloat *const angularVelocity, const MFloat dt, const MFloat *const qIn, MFloat *const qOut)
 Advance the rotational state by one timestep for a given angular velocity. More...
 
void quaternionToEuler (const MFloat *const quaternion, MFloat *const angles)
 Transform the quaternion to Euler angles. More...
 
void initTimers ()
 
void averageTimer ()
 
void readProperties ()
 Reading all necessary properties for the RigidBodies solver. More...
 
void initBodyData ()
 Allocating and initializing body data necessary for the solver run. More...
 
MFloat findClosestPointEllipsoid (const MFloat *const relPos, const MInt bodyId)
 
MFloat distancePointEllipsoid (const std::array< MFloat, 3 > e, const std::array< MFloat, 3 > y, std::array< MFloat, 3 > x)
 Calculates the closest distance between a given point and a ellipsoid in 3D. More...
 
void collideBodies ()
 Calculate collisions forces for all bodies. More...
 
void collideSpheres (const MInt bodyA, const MInt bodyB)
 Calculate collision force between two spheres. More...
 
MString outputDir () const
 
MFloat c_cellLengthAtMaxLevel () const
 
MFloat currMaxLevel () const
 
MFloat globBBox (MInt n)
 
MInt localToRemoteBody (const MInt collectorId, const MInt oldBodyId, const MInt domain)
 this function transforms a localBody to a remoteBody on the current domain, necessary if a body crosses a partition boundary to another partition More...
 
void deleteIrrelevantBodies (std::list< std::pair< MInt, MInt > > &removeList)
 Delete remote bodies from collector that are not relevant anymore. More...
 
void deleteDummyBody (const MInt bodyId, const MInt collectorShift=0)
 Delete dummy bodies from collector that are not relevant anymore. More...
 
void predictRotation (const MInt bodyId)
 Perform the prediction for the rotational state of a single body in 3D. More...
 
void predictRotation (const MInt)
 Empty function for the 2D rotation prediction. More...
 
void correctRotation (const MInt bodyId)
 Perform the correction for the rotational state for a single body in 3D. More...
 
void correctRotation (const MInt)
 Empty function for the 2D rotation correction. More...
 
MFloat findClosestPointEllipsoid (const MFloat *const, const MInt)
 Calculates the closest distance between a given point and a ellipsoid 2D. More...
 
MFloat findClosestPointEllipsoid (const MFloat *const relPos, const MInt bodyId)
 Calculates the closest distance between a given point and a ellipsoid in 3D. More...
 

Private Attributes

MBool m_newTimeStep = true
 
maia::rb::collector::RigidBodyCollector< nDim > m_bodies
 
maia::rb::collector::RigidBodyCollector< nDim > m_bResFile
 
MFloat m_bodyHeight {}
 
const MFloat m_bodyHeatCapacity = 1.0
 
MFloat m_uniformBodyTemperature {}
 
MString m_outputDir
 
MInt m_maxNoBodies {}
 
MInt m_noEmbeddedBodies = 1
 
MString m_bodyCenterInitMethod {}
 
MInt m_bodyType = 1
 
MInt m_restartTimeStep = 0
 
MBool m_forcedMotion = false
 
MBool m_translation = true
 
MBool m_rotation = true
 
MBool m_rotXYaxis = true
 
MBool m_restart = false
 
std::array< MFloat, nDim > gravity {}
 
MString m_restartDir
 
std::vector< MStringm_logVars
 
std::vector< MStringm_logAngVars
 
MFloat m_uRef {}
 
MFloat m_timestep = 0
 
MInt m_timesteps = 0
 
std::vector< MFloatm_initialBodyCenters
 
std::vector< MFloatm_initBodyDensityRatios
 
std::vector< MFloatm_initBodyRadius
 
std::vector< MFloatm_initBodyRadii
 
MBool m_static_computeBodyProperties_first = true
 
MFloatm_static_computeBodyProperties_amplitude = nullptr
 
MFloatm_static_computeBodyProperties_freqFactor = nullptr
 
MFloatm_static_computeBodyProperties_initialBodyCenter = nullptr
 
MFloatm_static_computeBodyProperties_Strouhal = nullptr
 
MFloatm_static_computeBodyProperties_mu = nullptr
 
MFloatm_static_computeBodyProperties_mu2 = nullptr
 
MFloatm_static_computeBodyProperties_liftStartAngle1 = nullptr
 
MFloatm_static_computeBodyProperties_liftEndAngle1 = nullptr
 
MFloatm_static_computeBodyProperties_liftStartAngle2 = nullptr
 
MFloatm_static_computeBodyProperties_liftEndAngle2 = nullptr
 
MFloatm_static_computeBodyProperties_circleStartAngle = nullptr
 
MFloatm_static_computeBodyProperties_normal = nullptr
 
MIntm_static_computeBodyProperties_bodyToFunction = nullptr
 
MFloatm_static_computeBodyProperties_omega = nullptr
 
MFloatm_static_computeBodyProperties_rotAngle = nullptr
 
std::array< MInt, Timers::_countm_timers
 
MString m_timerType
 
MInt m_noLocalBodies = 0
 
MInt m_noRemoteBodies = 0
 
MInt m_noDummyBodies = 0
 
std::vector< MIntm_indirectHomeDomains
 
std::vector< std::vector< MInt > > m_transferBodies
 
std::map< MInt, MIntm_associatedDummyBodies
 
std::map< MInt, std::vector< MInt > > m_remoteDomainLocalBodies
 
std::map< MInt, std::vector< MInt > > m_homeDomainRemoteBodies
 
std::map< MInt, std::map< MInt, std::array< MFloat, nDim > > > m_periodicShift
 
std::vector< MIntm_globalBodyIds
 
MBool m_periodicBC = false
 
std::array< MFloat, nDim > m_globDomainLength
 

Static Private Attributes

static constexpr MInt nRot = (nDim == 3) ? 3 : 1
 
static constexpr MInt nQuat = (nDim == 3) ? 4 : 0
 

Additional Inherited Members

- Protected Types inherited from maia::CartesianSolver< nDim, RigidBodies< nDim > >
using fun = void(CartesianSolver< nDim, RigidBodies< nDim > >::*)(std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
- Protected Member Functions inherited from maia::CartesianSolver< nDim, RigidBodies< nDim > >
void identifyBoundaryCells (MBool *const isInterface, const std::vector< MInt > &bndCndIds=std::vector< MInt >())
 
void identifyBoundaryCells ()
 
MBool cellIsOnGeometry (MInt cellId, Geometry< nDim > *geom)
 checks whether a cell lies on a certain geometry copied the essential part from identifyBoundaryCells More...
 
void setBoundaryDistance (const MBool *const interfaceCell, const MFloat *const outerBandWidth, MFloatScratchSpace &distance)
 transverses over all neighboring cells for a specified length More...
 
void markSurrndCells (MIntScratchSpace &inList, const MInt bandWidth, const MInt level, const MBool refineDiagonals=true)
 
void receiveWindowTriangles ()
 Receives triangles from neighbors contained in their window cells and inserts them locally. More...
 
void compactCells ()
 Removes all holes in the cell collector and moves halo cells to the back of the collector. More...
 
MInt createCellId (const MInt gridCellId)
 
void removeCellId (const MInt cellId)
 
MInt inCell (const MInt cellId, MFloat *point, MFloat fac=F1)
 
MInt setUpInterpolationStencil (const MInt cellId, MInt *, const MFloat *, std::function< MBool(MInt, MInt)>, MBool allowIncompleteStencil)
 
MFloat interpolateFieldData (MInt *, MFloat *, MInt varId, std::function< MFloat(MInt, MInt)> scalarField, std::function< MFloat(MInt, MInt)> coordinate)
 
MFloat leastSquaresInterpolation (MInt *, MFloat *, MInt varId, std::function< MFloat(MInt, MInt)> scalarField, std::function< MFloat(MInt, MInt)> coordinate)
 
void checkNoHaloLayers ()
 check that each solver has the required number of haloLayers for leaf cells!!! TODO labels:toenhance under production, needs to be cleaned up! More...
 
void mapInterpolationCells (std::map< MInt, MInt > &cellMap)
 
void setHaloCellsOnInactiveRanks ()
 
void patchRefinement (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)
 
void reOrderCellIds (std::vector< MInt > &reOrderedCells)
 reOrder cellIds before writing the restart file! This is necessary for example if the minLevel shall be raised at the new restart! More...
 
void recomputeGlobalIds (std::vector< MInt > &, std::vector< MLong > &)
 reOrder cellIds before writing the restart file! This is necessary for example if the minLevel shall be raised at the new restart! More...
 
void extractPointIdsFromGrid (Collector< PointBasedCell< nDim > > *&, Collector< CartesianGridPoint< nDim > > *&, const MBool, const std::map< MInt, MInt > &, MInt levelThreshold=999999, MFloat *bBox=nullptr, MBool levelSetMb=false) const
 Creates a list of unique corner points for all cells using a hash map levelThreshold optionally specifies the maximum cell level to be extracted bBox optionally specifies a bounding to box to which the extracted domain shall be truncated. More...
 
- Protected Member Functions inherited from Solver
 Solver (const MInt solverId, const MPI_Comm comm, const MBool isActive=true)
 
MFloat returnLoadRecord () const
 
MFloat returnIdleRecord () const
 
- Protected Attributes inherited from maia::CartesianSolver< nDim, RigidBodies< nDim > >
MIntm_rfnBandWidth
 
MInt m_noSensors
 
MInt m_adaptationInterval
 
MInt m_adaptationStep
 
std::vector< MIntm_maxSensorRefinementLevel
 
std::vector< MFloatm_sensorWeight
 
std::vector< MFloatm_sensorDerivativeVariables
 
MBool m_adaptation
 
MBool m_adapts
 
MInt m_noInitialSensors
 
MBool m_resTriggeredAdapt
 
MInt m_noSmoothingLayers
 
MInt m_sensorBandAdditionalLayers
 
MBool m_sensorInterface
 
MBool m_sensorParticle
 
std::vector< MStringm_sensorType
 
MIntm_recalcIds
 
std::vector< funm_sensorFnPtr
 
MInt m_maxNoSets
 
std::vector< MFloatm_azimuthalCartRecCoord
 
const MInt m_revDir [6]
 
const MInt m_noDirs
 
- Protected Attributes inherited from Solver
MFloat m_Re {}
 the Reynolds number More...
 
MFloat m_Ma {}
 the Mach number More...
 
MInt m_solutionInterval
 The number of timesteps before writing the next solution file. More...
 
MInt m_solutionOffset {}
 
std::set< MIntm_solutionTimeSteps
 
MInt m_restartInterval
 The number of timesteps before writing the next restart file. More...
 
MInt m_restartTimeStep
 
MInt m_restartOffset
 
MString m_solutionOutput
 
MBool m_useNonSpecifiedRestartFile = false
 
MBool m_initFromRestartFile
 
MInt m_residualInterval
 The number of timesteps before writing the next residual. More...
 
const MInt m_solverId
 a unique solver identifier More...
 
MFloatm_outerBandWidth = nullptr
 
MFloatm_innerBandWidth = nullptr
 
MIntm_bandWidth = nullptr
 
MBool m_restart = false
 
MBool m_restartFile = false
 

Detailed Description

template<MInt nDim>
class RigidBodies< nDim >

Definition at line 29 of file rigidbodies.h.

Member Typedef Documentation

◆ CartesianSolver

template<MInt nDim>
using RigidBodies< nDim >::CartesianSolver = typename maia::CartesianSolver<nDim, RigidBodies>

Definition at line 32 of file rigidbodies.h.

◆ Cell

template<MInt nDim>
using RigidBodies< nDim >::Cell = typename maia::grid::tree::Tree<nDim>::Cell

Definition at line 33 of file rigidbodies.h.

◆ Geom

template<MInt nDim>
using RigidBodies< nDim >::Geom = Geometry<nDim>

Definition at line 35 of file rigidbodies.h.

◆ Grid

template<MInt nDim>
using RigidBodies< nDim >::Grid = typename CartesianSolver::Grid

Definition at line 36 of file rigidbodies.h.

◆ GridProxy

template<MInt nDim>
using RigidBodies< nDim >::GridProxy = typename CartesianSolver::GridProxy

Definition at line 37 of file rigidbodies.h.

◆ Status

template<MInt nDim>
using RigidBodies< nDim >::Status = maia::rb::collector::Status

Definition at line 39 of file rigidbodies.h.

Constructor & Destructor Documentation

◆ RigidBodies()

template<MInt nDim>
RigidBodies< nDim >::RigidBodies ( const MInt  solverId_,
GridProxy gridProxy_,
Geom geometry_,
MPI_Comm  comm_ 
)
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
solverId_Unique solver id
gridProxy_Grid proxy representing the solvers grid information
geometry_Holding all relevant geometry information for this solver
comm_MPI communicator between all ranks responsible for this solver

Definition at line 32 of file rigidbodies.cpp.

33 : maia::CartesianSolver<nDim, RigidBodies<nDim>>(solverId_, gridProxy_, comm_), m_geometry(&geometry_) {
34 TRACE();
35
36 initTimers();
38
39#ifdef RB_DEBUG
40 m_debugFileStream.open("d" + std::to_string(domainId()) + ".txt");
41#endif
42
44
45 if(!domainId() && !m_restart) {
47 }
48
49 // create body communication mappings
54// for indirect neighbors (large bodies, to be improved)
55// exchangeNeighborConnectionInfo();
56#ifdef RB_DEBUG
58#endif
59 RECORD_TIMER_STOP(m_timers[Timers::Constructor]);
60}
std::ofstream m_debugFileStream
Definition: rigidbodies.h:322
void initBodyLog()
Initalize log-file.
void initGridProperties()
void initTimers()
Definition: rigidbodies.cpp:88
void printBodyDomainConnections()
debugging: print all necessary mappings for each partition in specific file
void readProperties()
Reading all necessary properties for the RigidBodies solver.
MBool m_restart
Definition: rigidbodies.h:176
void updateInfoDiameter(const MBool initCall=false)
void updateBodyDomainConnections(MBool initCall)
updates local/ edge body domain connections
void initBodyData()
Allocating and initializing body data necessary for the solver run.
void exchangeEdgeBodyData()
exchanges relevant body connections with new neighbor domains
std::array< MInt, Timers::_count > m_timers
Definition: rigidbodies.h:256
Geom * m_geometry
Definition: rigidbodies.h:79
virtual MInt domainId() const
Return the domainId (rank)
Definition: solver.h:383

◆ ~RigidBodies()

template<MInt nDim>
RigidBodies< nDim >::~RigidBodies
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de

Definition at line 68 of file rigidbodies.cpp.

68 {
69 TRACE();
70 // Close stream
71 if(!domainId()) {
72 m_anglog.close();
73 }
74
75#ifdef RB_DEBUG
76 m_debugFileStream.close();
77#endif
78 // Deallocate memory
79
80 // stop timer
81 RECORD_TIMER_STOP(m_timers[Timers::Class]);
82
85}
std::ofstream m_anglog
Definition: rigidbodies.h:321
void averageTimer()
void printScalingVariables()

Member Function Documentation

◆ a_angularAccelerationBody() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_angularAccelerationBody ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 571 of file rigidbodies.h.

571 {
572 return m_bodies.angularAccelerationBody(bodyId, dim);
573 }
maia::rb::collector::RigidBodyCollector< nDim > m_bodies
Definition: rigidbodies.h:152

◆ a_angularAccelerationBody() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_angularAccelerationBody ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 574 of file rigidbodies.h.

574 {
575 return m_bodies.angularAccelerationBody(bodyId, dim);
576 }

◆ a_angularAccelerationT1() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_angularAccelerationT1 ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 564 of file rigidbodies.h.

564 {
565 return m_bodies.angularAccelerationT1(bodyId, dim);
566 }

◆ a_angularAccelerationT1() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_angularAccelerationT1 ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 567 of file rigidbodies.h.

567 {
568 return m_bodies.angularAccelerationT1(bodyId, dim);
569 }

◆ a_angularVelocity() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_angularVelocity ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 588 of file rigidbodies.h.

588{ return a_angularVelocityT1(bodyId, dim); }
MFloat & a_angularVelocityT1(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:540

◆ a_angularVelocity() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_angularVelocity ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 589 of file rigidbodies.h.

589{ return a_angularVelocityT1(bodyId, dim); }

◆ a_angularVelocityBody() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_angularVelocityBody ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 591 of file rigidbodies.h.

591{ return a_angularVelocityBodyT1(bodyId, dim); }
MFloat & a_angularVelocityBodyT1(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:550

◆ a_angularVelocityBody() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_angularVelocityBody ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 592 of file rigidbodies.h.

592{ return a_angularVelocityBodyT1(bodyId, dim); }

◆ a_angularVelocityBodyT1() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_angularVelocityBodyT1 ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 550 of file rigidbodies.h.

550 {
551 return m_bodies.angularVelocityBodyT1(bodyId, dim);
552 }

◆ a_angularVelocityBodyT1() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_angularVelocityBodyT1 ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 553 of file rigidbodies.h.

553 {
554 return m_bodies.angularVelocityBodyT1(bodyId, dim);
555 }

◆ a_angularVelocityBodyT1B2() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_angularVelocityBodyT1B2 ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 557 of file rigidbodies.h.

557 {
558 return m_bodies.angularVelocityBodyT1B2(bodyId, dim);
559 }

◆ a_angularVelocityBodyT1B2() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_angularVelocityBodyT1B2 ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 560 of file rigidbodies.h.

560 {
561 return m_bodies.angularVelocityBodyT1B2(bodyId, dim);
562 }

◆ a_angularVelocityT1() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_angularVelocityT1 ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 540 of file rigidbodies.h.

540{ return m_bodies.angularVelocityT1(bodyId, dim); }

◆ a_angularVelocityT1() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_angularVelocityT1 ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 541 of file rigidbodies.h.

541 {
542 return m_bodies.angularVelocityT1(bodyId, dim);
543 }

◆ a_angularVelocityT1B2() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_angularVelocityT1B2 ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 545 of file rigidbodies.h.

545{ return m_bodies.angularVelocityT1B2(bodyId, dim); }

◆ a_angularVelocityT1B2() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_angularVelocityT1B2 ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 546 of file rigidbodies.h.

546 {
547 return m_bodies.angularVelocityT1B2(bodyId, dim);
548 }

◆ a_bodyAcceleration() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyAcceleration ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 509 of file rigidbodies.h.

509{ return m_bodies.bodyAcceleration(bodyId, dim); }

◆ a_bodyAcceleration() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyAcceleration ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 510 of file rigidbodies.h.

510{ return m_bodies.bodyAcceleration(bodyId, dim); }

◆ a_bodyAccelerationOld() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyAccelerationOld ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 512 of file rigidbodies.h.

512{ return m_bodies.bodyAccelerationOld(bodyId, dim); }

◆ a_bodyAccelerationOld() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyAccelerationOld ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 513 of file rigidbodies.h.

513 {
514 return m_bodies.bodyAccelerationOld(bodyId, dim);
515 }

◆ a_bodyCenter() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyCenter ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 497 of file rigidbodies.h.

497{ return m_bodies.bodyCenter(bodyId, dim); }

◆ a_bodyCenter() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyCenter ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 498 of file rigidbodies.h.

498{ return m_bodies.bodyCenter(bodyId, dim); }

◆ a_bodyCenterOld() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyCenterOld ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 500 of file rigidbodies.h.

500{ return m_bodies.bodyCenterOld(bodyId, dim); }

◆ a_bodyCenterOld() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyCenterOld ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 501 of file rigidbodies.h.

501{ return m_bodies.bodyCenterOld(bodyId, dim); }

◆ a_bodyDensityRatio() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyDensityRatio ( const MInt  bodyId)
inline

Definition at line 526 of file rigidbodies.h.

526{ return m_bodies.bodyDensityRatio(bodyId); }

◆ a_bodyDensityRatio() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyDensityRatio ( const MInt  bodyId) const
inline

Definition at line 527 of file rigidbodies.h.

527{ return m_bodies.bodyDensityRatio(bodyId); }

◆ a_bodyForce() [1/3]

template<MInt nDim>
MFloat * RigidBodies< nDim >::a_bodyForce ( const MInt  bodyId)
inline

Definition at line 493 of file rigidbodies.h.

493{ return &m_bodies.bodyForce(bodyId, 0); }

◆ a_bodyForce() [2/3]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyForce ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 494 of file rigidbodies.h.

494{ return m_bodies.bodyForce(bodyId, dim); }

◆ a_bodyForce() [3/3]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyForce ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 495 of file rigidbodies.h.

495{ return m_bodies.bodyForce(bodyId, dim); }

◆ a_bodyHeatFlux() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyHeatFlux ( const MInt  bodyId)
inline

Definition at line 523 of file rigidbodies.h.

523{ return m_bodies.bodyHeatFlux(bodyId); }

◆ a_bodyHeatFlux() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyHeatFlux ( const MInt  bodyId) const
inline

Definition at line 524 of file rigidbodies.h.

524{ return m_bodies.bodyHeatFlux(bodyId); }

◆ a_bodyInertia() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyInertia ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 529 of file rigidbodies.h.

529{ return m_bodies.bodyInertia(bodyId, dim); }

◆ a_bodyInertia() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyInertia ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 530 of file rigidbodies.h.

530{ return m_bodies.bodyInertia(bodyId, dim); }

◆ a_bodyMass()

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyMass ( const MInt  bodyId)
inline

Definition at line 466 of file rigidbodies.h.

466{ return a_bodyDensityRatio(bodyId) * a_volume(bodyId); }
MFloat & a_bodyDensityRatio(const MInt bodyId)
Definition: rigidbodies.h:526
MFloat a_volume(const MInt bodyId)
Definition: rigidbodies.h:468

◆ a_bodyQuaternionT1() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyQuaternionT1 ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 532 of file rigidbodies.h.

532{ return m_bodies.bodyQuaternionT1(bodyId, dim); }

◆ a_bodyQuaternionT1() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyQuaternionT1 ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 533 of file rigidbodies.h.

533{ return m_bodies.bodyQuaternionT1(bodyId, dim); }

◆ a_bodyQuaternionT1B2() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyQuaternionT1B2 ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 535 of file rigidbodies.h.

535{ return m_bodies.bodyQuaternionT1B2(bodyId, dim); }

◆ a_bodyQuaternionT1B2() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyQuaternionT1B2 ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 536 of file rigidbodies.h.

536 {
537 return m_bodies.bodyQuaternionT1B2(bodyId, dim);
538 }

◆ a_bodyRadii()

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyRadii ( const MInt  bodyId,
const MInt  n 
)
inline

Definition at line 480 of file rigidbodies.h.

480{ return m_bodies.bodyRadii(bodyId, n); }

◆ a_bodyRadius()

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyRadius ( const MInt  bodyId)
inline

Definition at line 481 of file rigidbodies.h.

481{ return m_bodies.bodyRadius(bodyId); }

◆ a_bodyTemperature() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyTemperature ( const MInt  bodyId)
inline

Definition at line 517 of file rigidbodies.h.

517{ return m_bodies.bodyTemperature(bodyId); }

◆ a_bodyTemperature() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyTemperature ( const MInt  bodyId) const
inline

Definition at line 518 of file rigidbodies.h.

518{ return m_bodies.bodyTemperature(bodyId); }

◆ a_bodyTemperatureOld() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyTemperatureOld ( const MInt  bodyId)
inline

Definition at line 520 of file rigidbodies.h.

520{ return m_bodies.bodyTemperatureOld(bodyId); }

◆ a_bodyTemperatureOld() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyTemperatureOld ( const MInt  bodyId) const
inline

Definition at line 521 of file rigidbodies.h.

521{ return m_bodies.bodyTemperatureOld(bodyId); }

◆ a_bodyTorque() [1/3]

template<MInt nDim>
MFloat * RigidBodies< nDim >::a_bodyTorque ( const MInt  bodyId)
inline

Definition at line 584 of file rigidbodies.h.

584{ return &m_bodies.torqueT1(bodyId, 0); }

◆ a_bodyTorque() [2/3]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyTorque ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 585 of file rigidbodies.h.

585{ return a_torqueT1(bodyId, dim); }
MFloat & a_torqueT1(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:578

◆ a_bodyTorque() [3/3]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyTorque ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 586 of file rigidbodies.h.

586{ return a_torqueT1(bodyId, dim); }

◆ a_bodyType()

template<MInt nDim>
MInt RigidBodies< nDim >::a_bodyType ( ) const
inline

Definition at line 610 of file rigidbodies.h.

610{ return m_bodyType; }
MInt m_bodyType
Definition: rigidbodies.h:170

◆ a_bodyVelocity() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyVelocity ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 503 of file rigidbodies.h.

503{ return m_bodies.bodyVelocity(bodyId, dim); }

◆ a_bodyVelocity() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyVelocity ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 504 of file rigidbodies.h.

504{ return m_bodies.bodyVelocity(bodyId, dim); }

◆ a_bodyVelocityMag()

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyVelocityMag ( const MInt  bodyId)
inline

Definition at line 600 of file rigidbodies.h.

600 {
601 MFloat velMag = 0.0;
602 for(MInt n = 0; n < nDim; n++) {
603 velMag += POW2(a_bodyVelocity(bodyId, n));
604 }
605 return sqrt(velMag);
606 }
MFloat & a_bodyVelocity(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:503
constexpr Real POW2(const Real x)
Definition: functions.h:119
int32_t MInt
Definition: maiatypes.h:62
double MFloat
Definition: maiatypes.h:52

◆ a_bodyVelocityOld() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_bodyVelocityOld ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 506 of file rigidbodies.h.

506{ return m_bodies.bodyVelocityOld(bodyId, dim); }

◆ a_bodyVelocityOld() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_bodyVelocityOld ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 507 of file rigidbodies.h.

507{ return m_bodies.bodyVelocityOld(bodyId, dim); }

◆ a_hasNeighbor()

template<MInt nDim>
MInt RigidBodies< nDim >::a_hasNeighbor ( const  MInt,
const  MInt 
) const
inline

Definition at line 101 of file rigidbodies.h.

101{ mTerm(1, AT_, "Not implemented for this solver!"); }
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29

◆ a_noCells()

template<MInt nDim>
MInt RigidBodies< nDim >::a_noCells ( ) const
inline

Definition at line 620 of file rigidbodies.h.

620{ return 0; }

◆ a_status() [1/2]

template<MInt nDim>
Status & RigidBodies< nDim >::a_status ( const MInt  bodyId)
inline

Definition at line 581 of file rigidbodies.h.

581{ return m_bodies.status(bodyId); }

◆ a_status() [2/2]

template<MInt nDim>
Status RigidBodies< nDim >::a_status ( const MInt  bodyId) const
inline

Definition at line 582 of file rigidbodies.h.

582{ return m_bodies.status(bodyId); }

◆ a_torqueT1() [1/2]

template<MInt nDim>
MFloat & RigidBodies< nDim >::a_torqueT1 ( const MInt  bodyId,
const MInt  dim 
)
inline

Definition at line 578 of file rigidbodies.h.

578{ return m_bodies.torqueT1(bodyId, dim); }

◆ a_torqueT1() [2/2]

template<MInt nDim>
MFloat RigidBodies< nDim >::a_torqueT1 ( const MInt  bodyId,
const MInt  dim 
) const
inline

Definition at line 579 of file rigidbodies.h.

579{ return m_bodies.torqueT1(bodyId, dim); }

◆ a_volume()

template<MInt nDim>
MFloat RigidBodies< nDim >::a_volume ( const MInt  bodyId)
inline

Definition at line 468 of file rigidbodies.h.

468 {
469 IF_CONSTEXPR(nDim == 2) { std::cout << "Revise volume for 2D!" << std::endl; }
470
471 MFloat volume = 1.0;
473 volume = PI * F4B3 * a_bodyRadii(bodyId, 0) * a_bodyRadii(bodyId, 1) * a_bodyRadii(bodyId, 2);
474 } else {
475 std::cerr << "Implement volume formula!" << std::endl;
476 }
477 return volume;
478 }
MInt a_bodyType() const
Definition: rigidbodies.h:610
MFloat & a_bodyRadii(const MInt bodyId, const MInt n)
Definition: rigidbodies.h:480

◆ addForce()

template<MInt nDim>
void RigidBodies< nDim >::addForce ( const MInt  bodyId,
const std::array< MFloat, nDim > &  force 
)
inline

Definition at line 438 of file rigidbodies.h.

438 {
439 for(MInt n = 0; n < nDim; n++) {
440 m_bodies.bodyForce(bodyId, n) += force[n];
441 }
442 }

◆ addTorque()

template<MInt nDim>
void RigidBodies< nDim >::addTorque ( const MInt  bodyId,
const std::array< MFloat, nRot > &  torque 
)
inline

Definition at line 444 of file rigidbodies.h.

444 {
445 if(!m_rotXYaxis && nRot == 3) {
446 a_bodyTorque(bodyId, 0) = 0.0;
447 a_bodyTorque(bodyId, 1) = 0.0;
448 a_bodyTorque(bodyId, 2) += torque[2];
449 } else {
450 for(MInt n = 0; n < nRot; n++) {
451 a_bodyTorque(bodyId, n) += torque[n];
452 }
453 }
454 }
MFloat * a_bodyTorque(const MInt bodyId)
Definition: rigidbodies.h:584
MBool m_rotXYaxis
Definition: rigidbodies.h:175
static constexpr MInt nRot
Definition: rigidbodies.h:131

◆ advanceBodies()

template<MInt nDim>
void RigidBodies< nDim >::advanceBodies
private
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de

Definition at line 1054 of file rigidbodies.cpp.

1054 {
1055 TRACE();
1056
1057 m_bodies.advanceBodies();
1058}

◆ advanceQuaternion()

template<MInt nDim>
void RigidBodies< nDim >::advanceQuaternion ( const MFloat *const  angularVelocity,
const MFloat  dt,
const MFloat *const  qIn,
MFloat *const  qOut 
)
inlineprivate
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
[in]angularVelocityAngular velocity
[in]dtTime step
[in]qInbodyQuaternion before the rotation
[out]qOutbodyQuaternion after the rotation

Definition at line 3170 of file rigidbodies.cpp.

3173 {
3174 const MFloat angularVelMag = sqrt(std::inner_product(angularVelocity, &angularVelocity[nRot], angularVelocity, 0.0));
3175
3176 MFloat qIncrement[4]{0.0, 0.0, 0.0, 1.0};
3177
3178 if(angularVelMag > 0.0) {
3179 const MFloat angle = 0.5 * angularVelMag * dt;
3180 const MFloat tmp = sin(angle) / angularVelMag;
3181 qIncrement[0] = tmp * angularVelocity[0];
3182 qIncrement[1] = tmp * angularVelocity[1];
3183 qIncrement[2] = tmp * angularVelocity[2];
3184 qIncrement[3] = cos(angle);
3185 }
3186
3187 maia::math::quatMult(qIncrement, qIn, qOut);
3188}
T cos(const T a, const T b, const T x)
Cosine slope filter.
Definition: filter.h:125
void quatMult(const MFloat *const qA, const MFloat *const qB, MFloat *const qC)
Definition: maiamath.h:482

◆ averageTimer()

template<MInt nDim>
void RigidBodies< nDim >::averageTimer
private

Definition at line 110 of file rigidbodies.cpp.

110 {
111 TRACE();
112 if(!grid().isActive()) return;
113
114 m_timerType = "max";
115 m_timerType = Context::getSolverProperty<MString>("timerType", m_solverId, AT_, &m_timerType);
116
117 // 0) map timer ids for safety
118
119 const MInt noTimers = m_timers.size();
120
121 // 1) fill buffer with local timer values
122 std::vector<MFloat> timerValues_;
123 timerValues_.reserve(noTimers);
124 for(MInt i = 0; i < noTimers; i++) {
125 timerValues_.emplace_back(RETURN_TIMER_TIME(m_timers[i]));
126 }
127
128 // 2) collect values from all ranks
129 if(m_timerType == "average") {
130 MPI_Allreduce(MPI_IN_PLACE, timerValues_.data(), noTimers, maia::type_traits<MFloat>::mpiType(), MPI_SUM, mpiComm(),
131 AT_, "MPI_IN_PLACE", "timerValues_");
132 } else {
133 MPI_Allreduce(MPI_IN_PLACE, timerValues_.data(), noTimers, maia::type_traits<MFloat>::mpiType(), MPI_MAX, mpiComm(),
134 AT_, "MPI_IN_PLACE", "timerValues_");
135 }
136
137 // 3) perform averaging on timer and4) set new timer values
138 if(m_timerType == "average") {
139 const MInt noDomains_ = noDomains();
140 for(MInt i = 0; i < noTimers; i++) {
141 const MFloat meanValue = timerValues_[i] / noDomains_;
142 SET_RECORD(m_timers[i], meanValue);
143 }
144 } else {
145 for(MInt i = 0; i < noTimers; i++) {
146 SET_RECORD(m_timers[i], timerValues_[i]);
147 }
148 }
149}
MPI_Comm mpiComm() const
Definition: rigidbodies.h:103
MString m_timerType
Definition: rigidbodies.h:257
const MInt m_solverId
a unique solver identifier
Definition: solver.h:90
virtual MInt noDomains() const
Definition: solver.h:387
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allreduce

◆ boxSeedInitialize()

template<MInt nDim>
void RigidBodies< nDim >::boxSeedInitialize

Definition at line 547 of file rigidbodies.cpp.

547 {
548 TRACE();
549
550 std::array<MFloat, nDim> bMin{};
551 std::array<MFloat, nDim> bMax{};
552
553 for(MInt n = 0; n < nDim; n++) {
554 bMin[n] = Context::getSolverProperty<MFloat>("seedBoxMin", m_solverId, AT_, n);
555 bMax[n] = Context::getSolverProperty<MFloat>("seedBoxMax", m_solverId, AT_, n);
556 }
557
558 MInt bodiesPerEdge = Context::getSolverProperty<MInt>("bodiesPerEdge", m_solverId, AT_, &bodiesPerEdge);
559 m_noEmbeddedBodies = pow(bodiesPerEdge, nDim);
560
561 std::array<std::vector<MFloat>, nDim> bodyGrid;
562 for(MInt n = 0; n < nDim; n++) {
563 bodyGrid[n] = maia::math::linSpace(bMin[n], bMax[n], bodiesPerEdge);
564 }
565
567 for(MInt i = 0; i < bodiesPerEdge; i++) {
568 MFloat x = bodyGrid[0][i];
569 for(MInt j = 0; j < bodiesPerEdge; j++) {
570 MFloat y = bodyGrid[1][j];
571 for(MInt k = 0; k < bodiesPerEdge; k++) {
572 MFloat z = bodyGrid[2][k];
573 m_initialBodyCenters[i * nDim * pow(bodiesPerEdge, 2) + j * nDim * bodiesPerEdge + k * nDim] = x;
574 m_initialBodyCenters[i * nDim * pow(bodiesPerEdge, 2) + j * nDim * bodiesPerEdge + k * nDim + 1] = y;
575 m_initialBodyCenters[i * nDim * pow(bodiesPerEdge, 2) + j * nDim * bodiesPerEdge + k * nDim + 2] = z;
576 }
577 }
578 }
579}
std::vector< MFloat > m_initialBodyCenters
Definition: rigidbodies.h:189
MInt m_noEmbeddedBodies
Definition: rigidbodies.h:168
int64_t MLong
Definition: maiatypes.h:64
std::vector< MFloat > linSpace(const MFloat start, const MFloat end, const MInt num)
Definition: maiamath.h:903
define array structures

◆ c_cellLengthAtMaxLevel()

template<MInt nDim>
MFloat RigidBodies< nDim >::c_cellLengthAtMaxLevel ( ) const
inlineprivate

Definition at line 268 of file rigidbodies.h.

268{ return grid().cellLengthAtLevel(currMaxLevel()); }
MFloat currMaxLevel() const
Definition: rigidbodies.h:270

◆ calculatePeriodicShift()

template<MInt nDim>
MFloat RigidBodies< nDim >::calculatePeriodicShift ( MInt  intersectingCellId,
MInt  direction 
)

shift will always point inwards

Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de
Parameters
direction[in][3]
intersectingCellId[in]
Returns
shift for given direction depending on the intersecting halo cell id

Definition at line 2043 of file rigidbodies.cpp.

2043 {
2044 TRACE();
2045 MFloat shift = F0;
2046 const MInt n = direction;
2047 const MBool periodicDir = grid().raw().periodicCartesianDir(n);
2048 const MBool periodicCell = grid().raw().a_hasProperty(intersectingCellId, Cell::IsPeriodic);
2049 if(m_periodicBC && periodicDir && periodicCell) {
2050 if(grid().raw().periodicCartesianDir(n)) {
2051 const MFloat cellCoordinate = grid().raw().a_coordinate(intersectingCellId, n);
2052 const MInt sign1 = maia::math::sgn(globBBox(n) - cellCoordinate);
2053 const MInt sign2 = maia::math::sgn(globBBox(n + nDim) - cellCoordinate);
2054 MFloat sign = F0;
2055 if(sign1 == 1 && sign2 == 1) {
2056 sign = 1.0;
2057 } else if(sign1 == -1 && sign2 == -1) {
2058 sign = -1.0;
2059 }
2060 shift = m_globDomainLength[n] * sign;
2061 }
2062 }
2063 return shift;
2064}
MBool m_periodicBC
Definition: rigidbodies.h:300
MFloat globBBox(MInt n)
Definition: rigidbodies.h:272
std::array< MFloat, nDim > m_globDomainLength
Definition: rigidbodies.h:301
bool MBool
Definition: maiatypes.h:58
MInt sgn(T val)
Definition: maiamath.h:495

◆ checkDummyBodiesForSwap()

template<MInt nDim>
void RigidBodies< nDim >::checkDummyBodiesForSwap

Definition at line 1827 of file rigidbodies.cpp.

1827 {
1828 TRACE();
1829
1830 if(m_associatedDummyBodies.empty()) return;
1831
1832 for(const auto& [bodyId, dummyId] : m_associatedDummyBodies) {
1833 MBool outside = -1 != grid().raw().findContainingHaloCell(&a_bodyCenter(bodyId, 0), -1, domainId(), true, nullptr);
1834 if(outside) {
1835 // swap body and its associated dummybody
1836 m_bodies.swap(bodyId, dummyId);
1837#ifdef RB_DEBUG
1838 m_debugFileStream << "body " << bodyId << " and associated dummyBody " << dummyId << " were swapped!"
1839 << std::endl;
1840#endif
1841 }
1842 }
1843}
MFloat & a_bodyCenter(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:497
std::map< MInt, MInt > m_associatedDummyBodies
Definition: rigidbodies.h:290

◆ cleanUp()

template<MInt nDim>
void RigidBodies< nDim >::cleanUp ( )
inlinevirtual

Implements Solver.

Definition at line 91 of file rigidbodies.h.

91{};

◆ collideBodies()

template<MInt nDim>
void RigidBodies< nDim >::collideBodies
private
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de

Definition at line 4177 of file rigidbodies.cpp.

4177 {
4178 TRACE();
4179 for(MInt bodyA = 0; bodyA < noConnectingBodies(); bodyA++) {
4180 // collide local with local Bodies
4181 for(MInt bodyB = 0; bodyB < noConnectingBodies(); bodyB++) {
4182 if(bodyA == bodyB) {
4183 continue;
4184 }
4185 collideSpheres(bodyA, bodyB);
4186 }
4187 }
4188}
void collideSpheres(const MInt bodyA, const MInt bodyB)
Calculate collision force between two spheres.
MInt noConnectingBodies() const
Definition: rigidbodies.h:423

◆ collideSpheres()

template<MInt nDim>
void RigidBodies< nDim >::collideSpheres ( const MInt  bodyA,
const MInt  bodyB 
)
private
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
bodyA[in]Id of the first body
bodyB[in]Id of the second body

Definition at line 4199 of file rigidbodies.cpp.

4199 {
4200 TRACE();
4201 // TODO labels:toenhance support bodies with different radii
4202 const MFloat S = 2.0 * c_cellLengthAtMaxLevel();
4203 const MFloat D = a_bodyRadius(bodyA) + a_bodyRadius(bodyB);
4204 // const MFloat termv = m_uRef;
4205
4206 MFloat delta = 0.0;
4207 for(MInt n = 0; n < nDim; n++) {
4208 delta += POW2(a_bodyCenter(bodyA, n) - a_bodyCenter(bodyB, n));
4209 }
4210 delta = sqrt(delta);
4211
4212 const MFloat dist = delta - D;
4213
4214 if(dist > S) {
4215 return;
4216 }
4217
4218 if(dist < F0) {
4219 std::cerr << "\033[0;31m Warning:\033[0m potential overlap for bodies" << bodyA << " " << bodyB << std::endl;
4220 }
4221
4222 const MFloat M = F1B2 * (a_bodyDensityRatio(bodyA) * a_volume(bodyA) + a_bodyDensityRatio(bodyB) * a_volume(bodyB));
4223 const MFloat C0 = 8.0 * M * POW2(2.0) / c_cellLengthAtMaxLevel();
4224
4225#ifdef RB_DEBUG
4226 std::array<MFloat, nDim> debug{};
4227#endif
4228 for(MInt i = 0; i < nDim; i++) {
4229 const MFloat df = C0 * POW2(mMax(F0, -(dist - S) / S)) * (a_bodyCenter(bodyA, i) - a_bodyCenter(bodyB, i)) / dist;
4230#ifdef RB_DEBUG
4231 debug[i] = df;
4232#endif
4233 a_bodyForce(bodyA, i) += df;
4234 }
4235#ifdef RB_DEBUG
4236 if(dist > F0) {
4237 std::cerr << "Contact force applied " << debug[0] << " " << debug[1] << " " << dist << " " << S << std::endl;
4238 }
4239#endif
4240}
MFloat & a_bodyRadius(const MInt bodyId)
Definition: rigidbodies.h:481
MFloat c_cellLengthAtMaxLevel() const
Definition: rigidbodies.h:268
MFloat * a_bodyForce(const MInt bodyId)
Definition: rigidbodies.h:493
constexpr T mMax(const T &x, const T &y)
Definition: functions.h:94
void debug(const MString &objectName, const MString &elementsName)
Debug output for mAlloc.
Definition: alloc.h:31
MFloat dist(const Point< DIM > &p, const Point< DIM > &q)
Definition: pointbox.h:54

◆ computeBodies()

template<MInt nDim>
void RigidBodies< nDim >::computeBodies

This is done via prediction or by using an analytic motion equation (forcedMotion)

Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de

Definition at line 657 of file rigidbodies.cpp.

657 {
658 TRACE();
659
660 // dimensionless RB time
662
663 if(m_forcedMotion) {
664 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
665 computeBodyPropertiesForced(1, &m_bodies.bodyCenter(bodyId, 0), bodyId, time);
666 computeBodyPropertiesForced(2, &m_bodies.bodyVelocity(bodyId, 0), bodyId, time);
667 computeBodyPropertiesForced(3, &m_bodies.bodyAcceleration(bodyId, 0), bodyId, time);
668 }
669 } else {
671 }
672}
MFloat time() const override
Return the time.
Definition: rigidbodies.h:93
MFloat m_timestep
Definition: rigidbodies.h:186
void predictorStep()
Peform a prediction for all bodies.
MBool m_forcedMotion
Definition: rigidbodies.h:172
void computeBodyPropertiesForced(MInt returnMode, MFloat *bodyData, MInt bodyId, MFloat time)
MInt m_noLocalBodies
Definition: rigidbodies.h:277
MInt globalTimeStep

◆ computeBodyPropertiesForced()

template<MInt nDim>
void RigidBodies< nDim >::computeBodyPropertiesForced ( MInt  returnMode,
MFloat bodyData,
MInt  bodyId,
MFloat  time 
)

◆ correctBodies()

template<MInt nDim>
void RigidBodies< nDim >::correctBodies
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de

Definition at line 930 of file rigidbodies.cpp.

930 {
931 TRACE();
932
933 if(!m_forcedMotion) {
936 }
937
938 logBodyData();
939}
void correctorStep()
Correct the state of all bodies using external forces/fluxes/torques.
void collideBodies()
Calculate collisions forces for all bodies.
void logBodyData()
Writing a simple log file containing the current state for all bodies.

◆ correctorStep()

template<MInt nDim>
void RigidBodies< nDim >::correctorStep
private
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de

Definition at line 2968 of file rigidbodies.cpp.

2968 {
2969 TRACE();
2970
2971 const MFloat dt = m_timestep;
2972 if(m_translation) {
2973 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
2974 // Translational values
2975 for(MInt n = 0; n < nDim; n++) {
2976 // Correct acceleration
2977 a_bodyAcceleration(bodyId, n) =
2978 a_bodyForce(bodyId, n) / a_bodyMass(bodyId)
2979 + gravity[n] * (1.0 - 1.0 / a_bodyDensityRatio(bodyId)); // Subtract bouyancy force
2980
2981 // Correct velocities
2982 a_bodyVelocity(bodyId, n) = a_bodyVelocityOld(bodyId, n)
2983 + 0.5 * dt * (a_bodyAcceleration(bodyId, n) + a_bodyAccelerationOld(bodyId, n));
2984
2985 // Correct position
2986 a_bodyCenter(bodyId, n) =
2987 a_bodyCenterOld(bodyId, n) + dt * a_bodyVelocityOld(bodyId, n)
2988 + 0.25 * POW2(dt) * (a_bodyAcceleration(bodyId, n) + a_bodyAccelerationOld(bodyId, n));
2989 }
2990
2991 if(m_rotation) {
2992 correctRotation(bodyId);
2993 }
2994
2995 // Scalar values
2996 // Correct temperature
2997 a_bodyTemperature(bodyId) = F1B2
2998 * (a_bodyTemperature(bodyId) + a_bodyTemperatureOld(bodyId)
2999 + dt * a_bodyHeatFlux(bodyId) / (m_bodyHeatCapacity * a_bodyMass(bodyId)));
3000 }
3001
3002 } else {
3003 if(m_rotation) {
3004 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
3005 correctRotation(bodyId);
3006 }
3007 }
3008 }
3009}
MFloat & a_bodyTemperature(const MInt bodyId)
Definition: rigidbodies.h:517
std::array< MFloat, nDim > gravity
Definition: rigidbodies.h:177
void correctRotation(const MInt bodyId)
MFloat & a_bodyVelocityOld(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:506
MFloat a_bodyMass(const MInt bodyId)
Definition: rigidbodies.h:466
const MFloat m_bodyHeatCapacity
Definition: rigidbodies.h:160
MBool m_rotation
Definition: rigidbodies.h:174
MFloat & a_bodyCenterOld(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:500
MBool m_translation
Definition: rigidbodies.h:173
MFloat & a_bodyTemperatureOld(const MInt bodyId)
Definition: rigidbodies.h:520
MFloat & a_bodyHeatFlux(const MInt bodyId)
Definition: rigidbodies.h:523
MFloat & a_bodyAccelerationOld(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:512
MFloat & a_bodyAcceleration(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:509

◆ correctRotation() [1/3]

void RigidBodies< 3 >::correctRotation ( const MInt  bodyId)
inlineprivate

For reference, see L.J.H. Seelen et al., Improved bodyQuaternion-based integration scheme for rigid body motion

Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
bodyIdBody id for which the correction is performed

Definition at line 3022 of file rigidbodies.cpp.

3022 {
3023 const MFloat dt = m_timestep;
3024
3025 MFloat torqueBodyT1[nRot];
3026 // Transform torque to the body frame
3027 transformToBodyFrame(&a_bodyQuaternionT1(bodyId, 0), &a_torqueT1(bodyId, 0), torqueBodyT1);
3028
3029 // Calculate angular momentum in the body frame
3030 MFloat angularMomentumBody[nRot]{};
3031 for(MInt n = 0; n < nRot; n++) {
3032 angularMomentumBody[n] = a_bodyInertia(bodyId, n) * a_angularVelocityBodyT1(bodyId, n);
3033 }
3034
3035 // Calculate convective part of the angular acceleration
3036 MFloat convectiveTerm[nRot]{};
3037 maia::math::cross(&a_angularVelocityBodyT1(bodyId, 0), &angularMomentumBody[0], &convectiveTerm[0]);
3038
3039 // Calculate angular acceleration
3040 MFloat angularAccelerationBodyT1[nRot]{};
3041 for(MInt n = 0; n < nRot; n++) {
3042 angularAccelerationBodyT1[n] = 1 / a_bodyInertia(bodyId, n) * (torqueBodyT1[n] - convectiveTerm[n]);
3043 }
3044 transformToWorldFrame(&a_bodyQuaternionT1(bodyId, 0), angularAccelerationBodyT1, &a_angularAccelerationT1(bodyId, 0));
3045
3046 // Advance angular velocity from time t+1/2 to time t+3/4
3047 MFloat angularVelocityBodyT3B2[nRot]{};
3048 for(MInt n = 0; n < nRot; n++) {
3049 angularVelocityBodyT3B2[n] = a_angularVelocityBodyT1B2(bodyId, n) + dt * angularAccelerationBodyT1[n];
3050 }
3051
3052 // Advance bodyQuaternion from time t+1/2 to time t+3/2
3053 MFloat bodyQuaternionT3B2[nQuat]{};
3054 advanceQuaternion(&a_angularVelocityT1(bodyId, 0), dt, &a_bodyQuaternionT1B2(bodyId, 0), bodyQuaternionT3B2);
3055
3056 // Transform angular velocity to the world frame
3057 MFloat angularVelocityT3B2[nRot]{};
3058 transformToWorldFrame(bodyQuaternionT3B2, angularVelocityBodyT3B2, angularVelocityT3B2);
3059
3060 // Advance time step
3061 constexpr MLong size_rot = nRot * sizeof(MFloat);
3062 constexpr MLong size_quat = nQuat * sizeof(MFloat);
3063
3064 memcpy(&a_angularAccelerationBody(bodyId, 0), angularAccelerationBodyT1, size_rot);
3065 memcpy(&a_angularVelocityBodyT1B2(bodyId, 0), angularVelocityBodyT3B2, size_rot);
3066 memcpy(&a_angularVelocityT1B2(bodyId, 0), angularVelocityT3B2, size_rot);
3067 memcpy(&a_bodyQuaternionT1B2(bodyId, 0), bodyQuaternionT3B2, size_quat);
3068}
void transformToBodyFrame(const MFloat *const quaternion, const MFloat *const vectorWorld, MFloat *const vectorBody)
Transform a vector form the world frame to the body frame.
void transformToWorldFrame(const MFloat *const quaternion, const MFloat *const vectorBody, MFloat *const vectorWorld)
Transform a vector form the body frame to the world frame.
MFloat & a_angularAccelerationBody(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:571
MFloat & a_angularVelocityT1B2(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:545
static constexpr MInt nQuat
Definition: rigidbodies.h:132
MFloat & a_bodyQuaternionT1B2(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:535
MFloat & a_angularAccelerationT1(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:564
void advanceQuaternion(const MFloat *const angularVelocity, const MFloat dt, const MFloat *const qIn, MFloat *const qOut)
Advance the rotational state by one timestep for a given angular velocity.
MFloat & a_bodyQuaternionT1(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:532
MFloat & a_angularVelocityBodyT1B2(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:557
MFloat & a_bodyInertia(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:529
void cross(const T *const u, const T *const v, T *const c)
Definition: maiamath.h:101

◆ correctRotation() [2/3]

template<MInt nDim>
void RigidBodies< nDim >::correctRotation ( const MInt  bodyId)
inlineprivate

◆ correctRotation() [3/3]

void RigidBodies< 2 >::correctRotation ( const  MInt)
inlineprivate
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
MIntBody id for wich the correction is performed

Definition at line 3078 of file rigidbodies.cpp.

3078 {
3079 std::cerr << "correctRotation: No implementation for 2D!" << std::endl;
3080}

◆ createDummyBody()

template<MInt nDim>
void RigidBodies< nDim >::createDummyBody ( MInt  bodyId)
Author
Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..des

Definition at line 2007 of file rigidbodies.cpp.

2007 {
2008 TRACE();
2009
2010 MInt newBodyId = noCollectorBodies();
2012 m_associatedDummyBodies[bodyId] = newBodyId;
2013 m_globalBodyIds.push_back(getGlobalBodyId(bodyId));
2014 m_bodies.append();
2015#ifdef RB_DEBUG
2016 m_debugFileStream << "Self-mapping case, adding dummy body to collector at " << newBodyId
2017 << " associated with bodyId " << bodyId << std::endl;
2018#endif
2019 // Initialize the dummyBuddy in collector
2020 a_bodyRadius(newBodyId) = a_bodyRadius(bodyId);
2021 a_bodyDensityRatio(newBodyId) = a_bodyDensityRatio(bodyId);
2022 a_bodyTemperature(newBodyId) = a_bodyTemperature(bodyId);
2023 a_bodyHeatFlux(newBodyId) = a_bodyHeatFlux(bodyId);
2024 for(MInt n = 0; n < nDim; n++) {
2025 a_bodyRadii(newBodyId, n) = a_bodyRadii(bodyId, n);
2026 a_bodyInertia(newBodyId, n) = a_bodyInertia(bodyId, n);
2027 }
2028}
MInt getGlobalBodyId(MInt localBodyId)
Definition: rigidbodies.h:415
MInt noCollectorBodies() const
Definition: rigidbodies.h:425
std::vector< MInt > m_globalBodyIds
Definition: rigidbodies.h:298
MInt m_noDummyBodies
Definition: rigidbodies.h:283

◆ currMaxLevel()

template<MInt nDim>
MFloat RigidBodies< nDim >::currMaxLevel ( ) const
inlineprivate

Definition at line 270 of file rigidbodies.h.

270{ return m_currMaxLevel; }
MInt m_currMaxLevel
Definition: rigidbodies.h:315

◆ deleteDummyBody()

template<MInt nDim>
void RigidBodies< nDim >::deleteDummyBody ( const MInt  bodyId,
const MInt  collectorShift = 0 
)
private
Author
Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de
Parameters
[in]bodyIdcorresponds to the localId of the body of which the associated dummy body has to be deleted
[in]collectorShiftdefault=0, if this function is called mutiple times to delete multiple bodies we generate a certain Shift inside the collector

Definition at line 2537 of file rigidbodies.cpp.

2537 {
2538 TRACE();
2539
2540 const MInt dummyBodyId = m_associatedDummyBodies[bodyId] - collectorShift;
2541
2542#ifdef RB_DEBUG
2543 m_debugFileStream << "Deleting Dummy Body " << m_associatedDummyBodies[bodyId] << " with corresponding bodyId "
2544 << bodyId << std::endl;
2545#endif
2546
2547 m_associatedDummyBodies.erase(bodyId);
2548 m_globalBodyIds.erase(std::remove(m_globalBodyIds.begin(), m_globalBodyIds.end(), dummyBodyId),
2549 m_globalBodyIds.end());
2550
2551 m_bodies.removeAndShift(dummyBodyId);
2553
2554 m_bodyWasDeleted = true;
2555
2556#ifdef RB_DEBUG
2558#endif
2559}
MBool m_bodyWasDeleted
Definition: rigidbodies.h:318

◆ deleteIrrelevantBodies()

template<MInt nDim>
void RigidBodies< nDim >::deleteIrrelevantBodies ( std::list< std::pair< MInt, MInt > > &  removeList)
private
Author
Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de
Parameters
[in]removeListlist containing pair of homeDomain and localId of remoteBody

Definition at line 2455 of file rigidbodies.cpp.

2455 {
2456 TRACE();
2457
2458 // Sort in descending order
2459 removeList.sort([](const std::pair<MInt, MInt>& a, const std::pair<MInt, MInt>& b) { return a.second > b.second; });
2460
2461 std::vector<MInt> removeListGlobIds;
2462 for(const auto& [homeDomain, body] : removeList) {
2463 removeListGlobIds.push_back(getGlobalBodyId(body));
2464 }
2465
2466 MInt collectorShiftIdx = 0;
2467 for(const auto& [homeDomain, body] : removeList) {
2468 m_bodyWasDeleted = true;
2469#ifdef RB_DEBUG
2470 m_debugFileStream << "Deleting remotebody " << body << " on domain " << domainId() << std::endl;
2471#endif
2472
2473 m_globalBodyIds.erase(
2474 std::remove(m_globalBodyIds.begin(), m_globalBodyIds.end(), removeListGlobIds[collectorShiftIdx]),
2475 m_globalBodyIds.end());
2476
2477 m_bodies.removeAndShift(body);
2479
2480 m_homeDomainRemoteBodies[homeDomain].erase(
2481 std::remove(m_homeDomainRemoteBodies[homeDomain].begin(), m_homeDomainRemoteBodies[homeDomain].end(), body),
2482 m_homeDomainRemoteBodies[homeDomain].end());
2483
2484 collectorShiftIdx++;
2485 // In case a remoteBody has also an associated dummy Body
2486 auto aDBCopy = m_associatedDummyBodies;
2487 for(auto& [bodyId, dummyId] : aDBCopy) {
2488 if(bodyId == body) {
2489 deleteDummyBody(bodyId, collectorShiftIdx);
2490 }
2491 }
2492 }
2493
2494#ifdef RB_DEBUG
2495 m_debugFileStream << "after deletion: " << std::endl;
2497#endif
2498
2499 // Adjust localIds in mapping accordingly
2500 for(std::list<std::pair<MInt, MInt>>::const_iterator it = removeList.cbegin(); it != removeList.cend(); it++) {
2501 for(auto& [domain, bodies] : m_homeDomainRemoteBodies) {
2502 // adjust localIds
2503 for(MInt& body : bodies) {
2504#ifdef RB_DEBUG
2505 m_debugFileStream << "body " << body << " it " << it->second << std::endl;
2506#endif
2507 if(body > it->second) {
2508 body--;
2509 }
2510 }
2511 }
2512 for(auto& [bodyId, dummyId] : m_associatedDummyBodies) {
2513#ifdef RB_DEBUG
2514 m_debugFileStream << "body " << bodyId << " with Dummybody " << dummyId << " it " << it->second << std::endl;
2515#endif
2516 if(dummyId > it->second) {
2517 dummyId--;
2518 }
2519 }
2520 }
2521
2522#ifdef RB_DEBUG
2523 m_debugFileStream << "after deletion and update of mappings: " << std::endl;
2525#endif
2526}
MInt m_noRemoteBodies
Definition: rigidbodies.h:280
void deleteDummyBody(const MInt bodyId, const MInt collectorShift=0)
Delete dummy bodies from collector that are not relevant anymore.
std::map< MInt, std::vector< MInt > > m_homeDomainRemoteBodies
Definition: rigidbodies.h:294
Definition: contexttypes.h:19

◆ distancePointEllipsoid()

template<MInt nDim>
MFloat RigidBodies< nDim >::distancePointEllipsoid ( const std::array< MFloat, 3 >  e,
const std::array< MFloat, 3 >  y,
std::array< MFloat, 3 >  x 
)
inlineprivate

Here, the point is given in the body frame of reference and the axis have been sorted by decreasing extension

Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
e[3][in]Extension of the ellipsoid in each direction
y[3][in]Point from which the distance is calculated
x[3][out]Closest point on the ellipsoids surface
Returns
Closest distance to the ellipsoid

Definition at line 3851 of file rigidbodies.cpp.

3852 {
3853 constexpr MFloat eps0 = 1e-12;
3854 constexpr MFloat eps1 = 1e-6;
3855 const MFloat dist0 = c_cellLengthAtMaxLevel();
3856 const MFloat dist1 = 10.0 * dist0;
3858 // Bisect to compute the root of F(t) for t >= -e2*e2.
3859 MFloat esqr[3] = {e[0] * e[0], e[1] * e[1], e[2] * e[2]};
3860 MFloat ey[3] = {e[0] * y[0], e[1] * y[1], e[2] * y[2]};
3861 MFloat r[3];
3862 MFloat t0 = -esqr[2] + ey[2];
3863 MFloat t1 = -esqr[2] + sqrt(ey[0] * ey[0] + ey[1] * ey[1] + ey[2] * ey[2]);
3864 MFloat t = t0;
3865 const int imax = 2 * std::numeric_limits<MFloat>::max_exponent;
3866 MFloat eps = eps1;
3867 if(fabs(t1 - t0) < eps) t1 = t0 + F2 * eps;
3868 MInt i = 0;
3869 distance = 1.0;
3870 while(fabs(t1 - t0) > eps && i < imax) {
3871 while(fabs(t1 - t0) > eps && i < imax) {
3872 i++;
3873 t = F1B2 * (t0 + t1);
3874 r[0] = ey[0] / (t + esqr[0]);
3875 r[1] = ey[1] / (t + esqr[1]);
3876 r[2] = ey[2] / (t + esqr[2]);
3877 MFloat f = r[0] * r[0] + r[1] * r[1] + r[2] * r[2] - F1;
3878 // f==0 also means convergence, intentionally?
3879 if(f >= F0) {
3880 t0 = t;
3881 }
3882 if(f <= F0) {
3883 t1 = t;
3884 }
3885 }
3886 x[0] = esqr[0] * y[0] / (t + esqr[0]);
3887 x[1] = esqr[1] * y[1] / (t + esqr[1]);
3888 x[2] = esqr[2] * y[2] / (t + esqr[2]);
3889 distance = sqrt(POW2(x[0] - y[0]) + POW2(x[1] - y[1]) + POW2(x[2] - y[2]));
3890 // adjust eps: small close to surface, larger further away from surface
3891 eps = eps0 + mMin(F1, mMax(F0, (distance - dist0) / (dist1 - dist0))) * (eps1 - eps0);
3892 }
3893
3894 if(fabs(t0 - t1) > eps) {
3895 std::cerr << std::setprecision(16) << "ellipsoid dist not converged! " << i << " " << t1 - t0 << std::endl;
3896 }
3897
3898 return distance;
3899}
constexpr T mMin(const T &x, const T &y)
Definition: functions.h:90
MFloat distance(const MFloat *a, const MFloat *b)
Definition: maiamath.h:249

◆ exchangeBodyVariablesAllToAll()

template<MInt nDim>
void RigidBodies< nDim >::exchangeBodyVariablesAllToAll

every domain has every current data for every body relevant to perform a solution step

Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de

Definition at line 1334 of file rigidbodies.cpp.

1334 {
1335 TRACE();
1336
1338 m_bResFile.append(noEmbeddedBodies());
1339
1340 // variables
1341 std::vector<MFloat*> transVarsRcv{&m_bResFile.bodyCenter(0, 0), &m_bResFile.bodyVelocity(0, 0),
1342 &m_bResFile.bodyAcceleration(0, 0)};
1343
1344 std::vector<MFloat*> rotVarsRcv{&m_bResFile.angularVelocityBodyT1B2(0, 0), &m_bResFile.angularAccelerationBody(0, 0)};
1345
1346 std::vector<MFloat*> quatVarsRcv{&m_bResFile.bodyQuaternionT1B2(0, 0), &m_bResFile.bodyQuaternionT1(0, 0)};
1347
1348 // bodyId + temperature + trans + rot + quat
1349 const MInt noTransVars = 3;
1350 const MInt noRotVars = 2;
1351 const MInt noQuatVars = 2;
1352 const MInt bufSizePerBody = 1 + 1 + noTransVars * nDim + noRotVars * nRot + noQuatVars * nQuat;
1353 MInt varSizeCount = 0;
1354 MInt bodySizeCount = 0;
1355 // create send buffer
1356 std::vector<MFloat> sendBuffer(MLong(m_noLocalBodies * bufSizePerBody));
1357 const MUint noToSend = sendBuffer.size();
1358
1359 // fill send buffer, if bodies are in collector
1360 if(m_bodies.size() > 0) {
1361 // send variables
1362 std::vector<MFloat*> transVars{&a_bodyCenter(0, 0), &a_bodyVelocity(0, 0), &a_bodyAcceleration(0, 0)};
1363 // MInt noTransVars = transVars.size();
1364
1365 std::vector<MFloat*> rotVars{&a_angularVelocityBodyT1B2(0, 0), &a_angularAccelerationBody(0, 0)};
1366 // MInt noRotVars = rotVars.size();
1367
1368 std::vector<MFloat*> quatVars{&a_bodyQuaternionT1B2(0, 0), &a_bodyQuaternionT1(0, 0)};
1369 // MInt noQuatVars = quatVars.size();
1370
1371 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
1372 sendBuffer[bodySizeCount] = (MFloat)getGlobalBodyId(bodyId);
1373 varSizeCount += 1;
1374
1375 // temperature
1376 sendBuffer[bodySizeCount + varSizeCount] = a_bodyTemperature(bodyId);
1377 varSizeCount += 1;
1378
1379 // trans vars
1380 for(MInt v = 0; v < noTransVars; v++) {
1381 for(MInt n = 0; n < nDim; n++) {
1382 sendBuffer[bodySizeCount + varSizeCount + n] = transVars[v][nDim * bodyId + n];
1383 }
1384 varSizeCount += nDim;
1385 }
1386 // rot vars
1387 for(MInt v = 0; v < noRotVars; v++) {
1388 for(MInt r = 0; r < nRot; r++) {
1389 sendBuffer[bodySizeCount + varSizeCount + r] = rotVars[v][nRot * bodyId + r];
1390 }
1391 varSizeCount += nRot;
1392 }
1393
1394 // quat vars
1395 for(MInt v = 0; v < noQuatVars; v++) {
1396 for(MInt q = 0; q < nQuat; q++) {
1397 sendBuffer[bodySizeCount + varSizeCount + q] = quatVars[v][nQuat * bodyId + q];
1398 }
1399 varSizeCount += nQuat;
1400 }
1401 bodySizeCount += bufSizePerBody;
1402 varSizeCount = 0;
1403 }
1404 }
1405
1406 // allocate receive buffer
1407 std::vector<MInt> noToRecv(noDomains());
1408 exchangeBufferLengthsAllToAll(noToRecv, noToSend);
1409 std::vector<MFloat> rcvBuffer(noEmbeddedBodies() * bufSizePerBody);
1410
1411 // displacements
1412 MInt count = 0;
1413 std::vector<MInt> displacements(noDomains());
1414 for(MInt n = 0; n < noDomains(); n++) {
1415 displacements[n] = count;
1416 count += noToRecv[n];
1417 }
1418
1419 // exchange data
1420 MPI_Allgatherv(sendBuffer.data(), sendBuffer.size(), maia::type_traits<MFloat>::mpiType(), rcvBuffer.data(),
1421 noToRecv.data(), displacements.data(), maia::type_traits<MFloat>::mpiType(), mpiComm(), AT_, "send",
1422 "recv");
1423
1424 // unpack receive buffer
1425 varSizeCount = 0;
1426 bodySizeCount = 0;
1427 for(MInt i = 0; i < noEmbeddedBodies(); i++) {
1428 const MInt bodyId = (MInt)rcvBuffer[bodySizeCount];
1429 varSizeCount += 1;
1430
1431 // temperature
1432 m_bResFile.bodyTemperature(bodyId) = rcvBuffer[bodySizeCount + varSizeCount];
1433 varSizeCount += 1;
1434
1435 // trans vars
1436 for(MInt v = 0; v < noTransVars; v++) {
1437 for(MInt n = 0; n < nDim; n++) {
1438 transVarsRcv[v][nDim * bodyId + n] = rcvBuffer[bodySizeCount + varSizeCount + n];
1439 }
1440 varSizeCount += nDim;
1441 }
1442 // rot vars
1443 for(MInt v = 0; v < noRotVars; v++) {
1444 for(MInt r = 0; r < nRot; r++) {
1445 rotVarsRcv[v][nRot * bodyId + r] = rcvBuffer[bodySizeCount + varSizeCount + r];
1446 }
1447 varSizeCount += nRot;
1448 }
1449
1450 // quat vars
1451 for(MInt v = 0; v < noQuatVars; v++) {
1452 for(MInt q = 0; q < nQuat; q++) {
1453 quatVarsRcv[v][nQuat * bodyId + q] = rcvBuffer[bodySizeCount + varSizeCount + q];
1454 }
1455 varSizeCount += nQuat;
1456 }
1457 bodySizeCount += bufSizePerBody;
1458 varSizeCount = 0;
1459 }
1460}
void exchangeBufferLengthsAllToAll(std::vector< MInt > &noToRecv, const MInt noToSend)
exchange of Buffer lengths all to all
MInt noEmbeddedBodies() const
Definition: rigidbodies.h:421
maia::rb::collector::RigidBodyCollector< nDim > m_bResFile
Definition: rigidbodies.h:155
uint32_t MUint
Definition: maiatypes.h:63
int MPI_Allgatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allgatherv

◆ exchangeBufferLengthsAllToAll()

template<MInt nDim>
void RigidBodies< nDim >::exchangeBufferLengthsAllToAll ( std::vector< MInt > &  noToRecv,
const MInt  noToSend 
)

serves as an mpi probe function

Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de

Definition at line 1259 of file rigidbodies.cpp.

1259 {
1260 TRACE();
1261 // exchange no of edge bodies to neighboring domains
1262 std::vector<MPI_Request> mpi_send_req(noDomains(), MPI_REQUEST_NULL);
1263 std::vector<MPI_Request> mpi_recv_req(noDomains(), MPI_REQUEST_NULL);
1264
1265 // recv from every domain and wait
1266 for(MInt n = 0; n < noDomains(); n++) {
1267 MPI_Irecv(&noToRecv[n], 1, MPI_INT, n, 2, mpiComm(), &mpi_recv_req[n], AT_, "recv buffer length");
1268 }
1269
1270 // send to root
1271 for(MInt n = 0; n < noDomains(); n++) {
1272 MPI_Isend(&noToSend, 1, MPI_INT, n, 2, mpiComm(), &mpi_send_req[n], AT_, "send buffer length");
1273 }
1274 // Wait for MPI exchange to complete
1275 MPI_Waitall(noDomains(), mpi_send_req.data(), MPI_STATUSES_IGNORE, AT_);
1276 MPI_Waitall(noDomains(), mpi_recv_req.data(), MPI_STATUSES_IGNORE, AT_);
1277}
int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &varname)
same as MPI_Isend
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &varname)
same as MPI_Irecv
int MPI_Waitall(int count, MPI_Request *request, MPI_Status *status, const MString &name)
same as MPI_Waitall

◆ exchangeBufferLengthsAllToRoot()

template<MInt nDim>
void RigidBodies< nDim >::exchangeBufferLengthsAllToRoot ( std::vector< MInt > &  noToRecv,
const MInt  noToSend 
)

serves as an mpi probe function

Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de

Definition at line 1228 of file rigidbodies.cpp.

1228 {
1229 TRACE();
1230
1231 MPI_Request mpi_send_req = MPI_REQUEST_NULL;
1232 std::vector<MPI_Request> mpi_recv_req(noDomains(), MPI_REQUEST_NULL);
1233
1234 // recv from every domain and wait
1235 if(!domainId()) {
1236 for(MInt n = 0; n < noDomains(); n++) {
1237 MPI_Irecv(&noToRecv[n], 1, MPI_INT, n, 2, mpiComm(), &mpi_recv_req[n], AT_, "recv buffer length");
1238 }
1239 }
1240
1241 // send to root
1242 MPI_Isend(&noToSend, 1, MPI_INT, 0, 2, mpiComm(), &mpi_send_req, AT_, "send buffer length");
1243
1244 // Wait for MPI exchange to complete
1245 MPI_Waitall(noDomains(), mpi_recv_req.data(), MPI_STATUS_IGNORE, AT_);
1246
1247 // Wait for MPI exchange to complete
1248 MPI_Wait(&mpi_send_req, MPI_STATUS_IGNORE, AT_);
1249}
int MPI_Wait(MPI_Request *request, MPI_Status *status, const MString &name)
same as MPI_Wait

◆ exchangeBufferLengthsNeighbor() [1/2]

template<MInt nDim>
void RigidBodies< nDim >::exchangeBufferLengthsNeighbor ( std::vector< MInt > &  noToRecv,
std::map< MInt, std::vector< MInt > > &  bodyList 
)

serves as an mpi probe function

Parameters
[in]noToRecvcount of bodies to receive for a neighbor domain
[in]bodyListmap like remoteDomainLocalBodies
Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de

Definition at line 1188 of file rigidbodies.cpp.

1189 {
1190 TRACE();
1191
1192 // exchange no of edge bodies to neighboring domains
1193 std::vector<MPI_Request> mpi_send_req(noNeighborDomains(), MPI_REQUEST_NULL);
1194 std::vector<MPI_Request> mpi_recv_req(noNeighborDomains(), MPI_REQUEST_NULL);
1195
1196 // recv from every neighbor
1197 for(MInt n = 0; n < noNeighborDomains(); n++) {
1198 MPI_Irecv(&noToRecv[n], 1, MPI_INT, neighborDomain(n), 2, mpiComm(), &mpi_recv_req[n], AT_, "recv predict");
1199 }
1200
1201 // create send buffer
1202 std::vector<MUint> sendBuffer(noNeighborDomains(), 0);
1203 for(MInt d = 0; d < noNeighborDomains(); d++) {
1204 MInt globDomain = neighborDomain(d);
1205 sendBuffer[d] = bodyList[globDomain].size();
1206 }
1207
1208 // send to every neighbor
1209 for(MInt i = 0; i < noNeighborDomains(); i++) {
1210 MPI_Isend(&sendBuffer[i], 1, MPI_INT, neighborDomain(i), 2, mpiComm(), &mpi_send_req[i], AT_, "send predict");
1211 }
1212
1213 // Wait for MPI exchange to complete
1214 for(MInt i = 0; i < noNeighborDomains(); i++) {
1215 MPI_Wait(&mpi_send_req[i], MPI_STATUS_IGNORE, AT_);
1216 MPI_Wait(&mpi_recv_req[i], MPI_STATUS_IGNORE, AT_);
1217 }
1218}

◆ exchangeBufferLengthsNeighbor() [2/2]

template<MInt nDim>
void RigidBodies< nDim >::exchangeBufferLengthsNeighbor ( std::vector< MInt > &  noToRecv,
std::vector< std::vector< MInt > > &  bodyList 
)

serves as an mpi probe function

Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de

Definition at line 1145 of file rigidbodies.cpp.

1146 {
1147 TRACE();
1148
1149 // exchange no of edge bodies to neighboring domains
1150 std::vector<MPI_Request> mpi_send_req(noNeighborDomains(), MPI_REQUEST_NULL);
1151 std::vector<MPI_Request> mpi_recv_req(noNeighborDomains(), MPI_REQUEST_NULL);
1152
1153 // recv from every neighbor
1154 for(MInt n = 0; n < noNeighborDomains(); n++) {
1155 MPI_Irecv(&noToRecv[n], 1, MPI_INT, neighborDomain(n), 2, mpiComm(), &mpi_recv_req[n], AT_, "recv predict");
1156 }
1157
1158 // create send buffer
1159 std::vector<MUint> sendBuffer(noNeighborDomains(), 0);
1160 for(MInt d = 0; d < noNeighborDomains(); d++) {
1161 sendBuffer[d] = bodyList[d].size();
1162 }
1163
1164 // send to every neighbor
1165 for(MInt i = 0; i < noNeighborDomains(); i++) {
1166 MPI_Isend(&sendBuffer[i], 1, MPI_INT, neighborDomain(i), 2, mpiComm(), &mpi_send_req[i], AT_, "send predict");
1167 }
1168
1169 // Wait for MPI exchange to complete
1170 for(MInt i = 0; i < noNeighborDomains(); i++) {
1171 MPI_Wait(&mpi_send_req[i], MPI_STATUS_IGNORE, AT_);
1172 MPI_Wait(&mpi_recv_req[i], MPI_STATUS_IGNORE, AT_);
1173 }
1174}

◆ exchangeBufferLengthsNeighbors()

template<MInt nDim>
void RigidBodies< nDim >::exchangeBufferLengthsNeighbors ( std::vector< MInt > &  noToRecv,
const MInt  noToSend 
)

Definition at line 1283 of file rigidbodies.cpp.

1283 {
1284 TRACE();
1285 // exchange no of edge bodies to neighboring domains
1286 std::vector<MPI_Request> mpi_send_req(noNeighborDomains(), MPI_REQUEST_NULL);
1287 std::vector<MPI_Request> mpi_recv_req(noNeighborDomains(), MPI_REQUEST_NULL);
1288
1289 // recv from every domain and wait
1290 for(MInt n = 0; n < noNeighborDomains(); n++) {
1291 MPI_Irecv(&noToRecv[n], 1, MPI_INT, neighborDomain(n), 2, mpiComm(), &mpi_recv_req[n], AT_, "recv buffer length");
1292 }
1293
1294 // send to root
1295 for(MInt n = 0; n < noNeighborDomains(); n++) {
1296 MPI_Isend(&noToSend, 1, MPI_INT, neighborDomain(n), 2, mpiComm(), &mpi_send_req[n], AT_, "send buffer length");
1297 }
1298 // Wait for MPI exchange to complete
1299 MPI_Waitall(noNeighborDomains(), mpi_send_req.data(), MPI_STATUSES_IGNORE, AT_);
1300 MPI_Waitall(noNeighborDomains(), mpi_recv_req.data(), MPI_STATUSES_IGNORE, AT_);
1301}

◆ exchangeBufferLengthsRemoteToHome()

template<MInt nDim>
void RigidBodies< nDim >::exchangeBufferLengthsRemoteToHome ( std::vector< MInt > &  noToRecv,
std::vector< MInt > &  noToSend 
)

Definition at line 1107 of file rigidbodies.cpp.

1107 {
1108 TRACE();
1109
1110 std::vector<MPI_Request> mpi_send_req(noHomeDomains(), MPI_REQUEST_NULL);
1111 std::vector<MPI_Request> mpi_recv_req(noRemoteDomains(), MPI_REQUEST_NULL);
1112
1113 // recv from every neighbor
1114 MInt count = 0;
1115 for(const auto& [remoteDomain, bodies] : m_remoteDomainLocalBodies) {
1116 MPI_Irecv(&noToRecv[count], 1, MPI_INT, remoteDomain, 2, mpiComm(), &mpi_recv_req[count], AT_, "recv from remote");
1117 count++;
1118 }
1119
1120 // send
1121 count = 0;
1122 for(const auto& [homeDomain, bodies] : m_homeDomainRemoteBodies) {
1123 MPI_Isend(&noToSend[count], 1, MPI_INT, homeDomain, 2, mpiComm(), &mpi_send_req[count], AT_, "send to home");
1124 count++;
1125 }
1126
1127 // wait for communication to finish
1128 for(MInt n = 0; n < noHomeDomains(); n++) {
1129 MPI_Wait(&mpi_send_req[n], MPI_STATUS_IGNORE, AT_);
1130 }
1131
1132 for(MInt n = 0; n < noRemoteDomains(); n++) {
1133 MPI_Wait(&mpi_recv_req[n], MPI_STATUS_IGNORE, AT_);
1134 }
1135}
std::map< MInt, std::vector< MInt > > m_remoteDomainLocalBodies
Definition: rigidbodies.h:292
MInt noHomeDomains() const
Definition: rigidbodies.h:427
MInt noRemoteDomains() const
Definition: rigidbodies.h:429

◆ exchangeEdgeBodyData()

template<MInt nDim>
void RigidBodies< nDim >::exchangeEdgeBodyData

and updates remaining (remote) body lists & mappings

Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de

Definition at line 2075 of file rigidbodies.cpp.

2075 {
2076 TRACE();
2077 // exchange no of edge bodies to neighboring domains
2078 std::vector<MInt> noToRecv(noNeighborDomains());
2080
2081 std::vector<MPI_Request> mpi_send_req(noNeighborDomains(), MPI_REQUEST_NULL);
2082 std::vector<MPI_Request> mpi_recv_req(noNeighborDomains(), MPI_REQUEST_NULL);
2083
2084 // create receive buffer
2085 std::vector<std::vector<MFloat>> rcvBufferAll(noNeighborDomains());
2086 MInt bufSizePerBody = 1 + nDim * 1 + nRot * 2 + nQuat * 2 + 3;
2087
2088 // if not shape, different body Radii have to be send
2089 if(a_bodyType() != Shapes::Sphere) {
2090 bufSizePerBody += nDim;
2091 }
2092
2093 for(MInt n = 0; n < noNeighborDomains(); n++) {
2094 rcvBufferAll[n].resize(noToRecv[n] * bufSizePerBody);
2095 }
2096
2097 // non-blocking receive
2098 for(MInt i = 0; i < noNeighborDomains(); i++) {
2099 if(!noToRecv[i]) {
2100 continue;
2101 }
2102
2103 MPI_Irecv(rcvBufferAll[i].data(), rcvBufferAll[i].size(), maia::type_traits<MFloat>::mpiType(), neighborDomain(i),
2104 2, mpiComm(), &mpi_recv_req[i], AT_, "recv predict");
2105 }
2106
2107 // create send buffer
2108 MInt idx = 0;
2109 MInt paraCount = 0;
2110 std::vector<std::vector<MFloat>> sendBufferAll(noNeighborDomains());
2111 for(MInt i = 0; i < noNeighborDomains(); i++) {
2112 MInt globDomain = neighborDomain(i);
2113 if(domainId() == globDomain) continue;
2114
2115 auto& tmpSendBuffer = sendBufferAll[i];
2116 tmpSendBuffer.resize(bufSizePerBody * m_remoteDomainLocalBodies[globDomain].size());
2117 idx = 0;
2118 for(const auto& body : m_remoteDomainLocalBodies[globDomain]) {
2119 paraCount = 0;
2120 // send corresponding globalId of body
2121 tmpSendBuffer[idx * bufSizePerBody] = (MFloat)getGlobalBodyId(body);
2122 paraCount++;
2123
2124 for(MInt n = 0; n < nDim; n++) {
2125 tmpSendBuffer[idx * bufSizePerBody + paraCount + n] = a_bodyCenter(body, n);
2126 }
2127 paraCount += nDim;
2128
2129 // necessary to exchange quaternions?
2130 for(MInt r = 0; r < nRot; r++) {
2131 tmpSendBuffer[idx * bufSizePerBody + paraCount + r] = a_angularAccelerationBody(body, r);
2132 tmpSendBuffer[idx * bufSizePerBody + paraCount + nRot + r] = a_angularVelocityBodyT1B2(body, r);
2133 }
2134 paraCount += 2 * nRot;
2135
2136 for(MInt q = 0; q < nQuat; q++) {
2137 tmpSendBuffer[idx * bufSizePerBody + paraCount + q] = a_bodyQuaternionT1(body, q);
2138 tmpSendBuffer[idx * bufSizePerBody + paraCount + nQuat + q] = a_bodyQuaternionT1B2(body, q);
2139 }
2140 paraCount += 2 * nQuat;
2141
2142 tmpSendBuffer[idx * bufSizePerBody + paraCount] = a_bodyRadius(body);
2143 paraCount++;
2144 if(a_bodyType() != Shapes::Sphere) {
2145 for(MInt n = 0; n < nDim; n++) {
2146 tmpSendBuffer[idx * bufSizePerBody + paraCount + n] = a_bodyRadii(body, n);
2147 }
2148 paraCount += nDim;
2149 }
2150
2151 tmpSendBuffer[idx * bufSizePerBody + paraCount] = a_bodyDensityRatio(body);
2152 paraCount++;
2153 tmpSendBuffer[idx * bufSizePerBody + paraCount] = a_bodyTemperature(body);
2154 paraCount++;
2155 idx++;
2156 }
2157 }
2158
2159 // non-blocking send
2160 for(MInt i = 0; i < noNeighborDomains(); i++) {
2161 MInt globDomain = neighborDomain(i);
2162 if(m_remoteDomainLocalBodies[globDomain].empty()) {
2163 continue;
2164 }
2165
2166 MPI_Isend(sendBufferAll[i].data(), sendBufferAll[i].size(), maia::type_traits<MFloat>::mpiType(), neighborDomain(i),
2167 2, mpiComm(), &mpi_send_req[i], AT_, "send predict");
2168 }
2169
2170 // wait for communication to finish
2171 for(MInt i = 0; i < noNeighborDomains(); i++) {
2172 MInt globDomain = neighborDomain(i);
2173 if(!m_remoteDomainLocalBodies[globDomain].empty()) {
2174 MPI_Wait(&mpi_send_req[i], MPI_STATUS_IGNORE, AT_);
2175 }
2176
2177 if(noToRecv[i]) {
2178 MPI_Wait(&mpi_recv_req[i], MPI_STATUS_IGNORE, AT_);
2179 }
2180 }
2181
2182 // All bodies, that are marked as remote on domain are added to remove list
2183 // it is checked if data for the body that was already remote is received
2184 // if not it is not relevant anymore and can be deleted from the mapping
2185 std::list<std::pair<MInt, MInt>> remoteBodyRemoveList;
2186 for(const auto& [homeDomain, bodies] : m_homeDomainRemoteBodies) {
2187 for(const MInt rBody : bodies) {
2188 remoteBodyRemoveList.push_back(std::make_pair(homeDomain, rBody));
2189 }
2190 }
2191
2192#ifdef RB_DEBUG
2193 MString removeListS = "[";
2194 for(const auto& body : remoteBodyRemoveList) {
2195 removeListS += "[" + std::to_string(body.first) + "," + std::to_string(body.second) + "]";
2196 }
2197 removeListS += "] ";
2198 m_debugFileStream << "Before: RemoveList for domain " << domainId() << " " << removeListS << std::endl;
2200#endif
2201
2202 // unpack buffer
2203 for(MInt n = 0; n < noNeighborDomains(); n++) {
2204 MInt globalDomain = neighborDomain(n);
2205 MInt mapIdx = 0;
2206 for(MInt b = 0; b < noToRecv[n]; b++) {
2207 paraCount = 0;
2208 MInt remoteBodyId = rcvBufferAll[n][b * bufSizePerBody];
2209 paraCount++;
2210
2211#ifdef RB_DEBUG
2212 m_debugFileStream << "domain: " << domainId() << " receives remoteBodyId: " << remoteBodyId << " from "
2213 << globalDomain << " with locId " << getLocalBodyId(remoteBodyId) << std::endl;
2214#endif
2215
2216 MInt localBodyId = getLocalBodyId(remoteBodyId);
2217 if(localBodyId != -1) {
2218 // received data for localBodyId, body is still relevant and therefore has to be eliminated again from list
2219 std::list<std::pair<MInt, MInt>>* a = &remoteBodyRemoveList;
2220 a->erase(std::remove_if(a->begin(), a->end(),
2221 [&localBodyId](std::pair<MInt, MInt> x) { return x.second == localBodyId; }),
2222 a->end());
2223
2224 for(const auto& [domain, bodies] : m_homeDomainRemoteBodies) {
2225 if(bodies.empty()) continue;
2226
2227 for(const auto& bodyId : bodies) {
2228 // check if body was previously in m_transferBodies -> homeDomain has changed and
2229 // mapping needs to be updated accordingly
2230 if(domain != globalDomain && localBodyId == bodyId) {
2231 // Body was transfered and has a new homeDomain
2232 std::vector<MInt>* c = &m_homeDomainRemoteBodies[domain];
2233 c->erase(std::remove(c->begin(), c->end(), localBodyId), c->end());
2234 m_homeDomainRemoteBodies[globalDomain].push_back(localBodyId);
2235 break;
2236 }
2237 }
2238 }
2239
2240 // Ensure the bodies in the mapping are in the received order
2241 // This is important for all communication buffers to be consistent
2242 std::vector<MInt>& remoteBodies = m_homeDomainRemoteBodies[globalDomain];
2243 auto actualPos = std::find(remoteBodies.begin(), remoteBodies.end(), localBodyId);
2244 auto wantedPos = remoteBodies.begin() + mapIdx;
2245 std::iter_swap(actualPos, wantedPos);
2246 mapIdx++;
2247 m_debugFileStream << "SWAP SWAP";
2248 for(auto&& r : remoteBodies) {
2249 m_debugFileStream << r << ",";
2250 }
2251 m_debugFileStream << std::endl;
2252
2253 } else {
2254 // we want to maintain the structure in the collector (localBodies | remoteBodies | dummyBodies)
2255 // therefore all relevant Mappings have to be updated accordingly
2256 // if there are no dummyBodies in collector we can simply append to collector
2257 if(m_associatedDummyBodies.empty()) {
2258 m_bodies.append();
2259 m_globalBodyIds.push_back(remoteBodyId);
2261 m_homeDomainRemoteBodies[globalDomain].push_back(m_globalBodyIds.size() - 1);
2262 mapIdx++;
2263 } else {
2264 // if there are already dummy Bodies in the collector
2265 // a new Remote Body is inserted in the collector in front of all dummy bodies
2266 MInt newIdx = noConnectingBodies();
2267 m_bodies.insert(newIdx);
2268 m_globalBodyIds.insert(m_globalBodyIds.begin() + newIdx, remoteBodyId);
2270 m_homeDomainRemoteBodies[globalDomain].push_back(newIdx);
2271 mapIdx++;
2272 for(auto& [bodyId, dummyId] : m_associatedDummyBodies) {
2273 dummyId++;
2274 }
2275 }
2276 }
2277
2278 const MInt newLocalBodyId = getLocalBodyId(remoteBodyId);
2279
2280 for(MInt d = 0; d < nDim; d++) {
2281 a_bodyCenter(newLocalBodyId, d) = rcvBufferAll[n][b * bufSizePerBody + paraCount + d];
2282 }
2283 paraCount += nDim;
2284
2285 for(MInt r = 0; r < nRot; r++) {
2286 a_angularAccelerationBody(newLocalBodyId, r) = rcvBufferAll[n][b * bufSizePerBody + paraCount + r];
2287 a_angularVelocityBodyT1B2(newLocalBodyId, r) = rcvBufferAll[n][b * bufSizePerBody + paraCount + nRot + r];
2288 }
2289 paraCount += 2 * nRot;
2290
2291 for(MInt q = 0; q < nQuat; q++) {
2292 a_bodyQuaternionT1(newLocalBodyId, q) = rcvBufferAll[n][b * bufSizePerBody + paraCount + q];
2293 a_bodyQuaternionT1B2(newLocalBodyId, q) = rcvBufferAll[n][b * bufSizePerBody + paraCount + nQuat + q];
2294 }
2295 paraCount += 2 * nQuat;
2296
2297 a_bodyRadius(newLocalBodyId) = rcvBufferAll[n][b * bufSizePerBody + paraCount];
2298 paraCount++;
2299 if(a_bodyType() != Shapes::Sphere) {
2300 for(MInt d = 0; d < nDim; d++) {
2301 a_bodyRadii(newLocalBodyId, d) = rcvBufferAll[n][b * bufSizePerBody + paraCount + d];
2302 }
2303 paraCount += nDim;
2304 } else {
2305 std::fill_n(&a_bodyRadii(newLocalBodyId, 0), nDim, a_bodyRadius(newLocalBodyId));
2306 }
2307
2308 a_bodyDensityRatio(newLocalBodyId) = rcvBufferAll[n][b * bufSizePerBody + paraCount];
2309 paraCount++;
2310 a_bodyTemperature(newLocalBodyId) = rcvBufferAll[n][b * bufSizePerBody + paraCount];
2311 paraCount++;
2312 a_bodyHeatFlux(newLocalBodyId) = 0.0;
2313
2314 // if domain receives a new remote Body, that has to be self-mapped on remoteDomain, create dummyBody
2315 const MInt remoteBodyIntersectsWithDomainId =
2316 grid().raw().intersectingWithHaloCells(&a_bodyCenter(newLocalBodyId, 0), m_infoDiameter / 2.0, 0, true);
2317 if(m_periodicBC && !hasAssociatedDummyBody(newLocalBodyId) && remoteBodyIntersectsWithDomainId != -1
2318 && grid().raw().a_hasProperty(remoteBodyIntersectsWithDomainId, Cell::IsPeriodic)) {
2319 createDummyBody(newLocalBodyId);
2320
2321 std::array<MFloat, nDim> center{};
2322 for(MInt d = 0; d < nDim; d++) {
2323 center[n] = a_bodyCenter(newLocalBodyId, n);
2324 }
2325
2326 for(MInt d = 0; d < nDim; d++) {
2327 m_periodicShift[domainId()][newLocalBodyId][d] = calculatePeriodicShift(remoteBodyIntersectsWithDomainId, d);
2328 }
2329 // initialize dummyBody kinematic data with the data of the remote Body
2330 initRemoteDummyBodyData(newLocalBodyId);
2331 }
2332 }
2333 }
2334
2335#ifdef RB_DEBUG
2336 if(!remoteBodyRemoveList.empty()) {
2337 removeListS = "[";
2338 for(const auto& body : remoteBodyRemoveList) {
2339 removeListS += "[" + std::to_string(body.first) + "," + std::to_string(body.second) + "]";
2340 }
2341 removeListS += "] ";
2342 m_debugFileStream << "After: RemoveList for domain " << domainId() << " " << removeListS << std::endl;
2343 }
2344#endif
2345
2346 deleteIrrelevantBodies(remoteBodyRemoveList);
2347}
std::map< MInt, std::map< MInt, std::array< MFloat, nDim > > > m_periodicShift
Definition: rigidbodies.h:296
MBool hasAssociatedDummyBody(const MInt bodyId) const
Definition: rigidbodies.h:431
void createDummyBody(MInt bodyId)
appends new DummyBody to collector
MFloat calculatePeriodicShift(MInt intersectingCellId, MInt direction)
periodic shift for position for further data exchange
void deleteIrrelevantBodies(std::list< std::pair< MInt, MInt > > &removeList)
Delete remote bodies from collector that are not relevant anymore.
void exchangeBufferLengthsNeighbor(std::vector< MInt > &noToRecv, std::vector< std::vector< MInt > > &bodyList)
exchange of Buffer legnths for further exchanges
void initRemoteDummyBodyData(const MInt bodyId)
initalize kinematic data of dummyBody that is associated with a remoteBody
MInt size() const
Definition: rigidbodies.h:407
MInt getLocalBodyId(MInt globalBodyId)
Definition: rigidbodies.h:408
MFloat m_infoDiameter
Definition: rigidbodies.h:313
std::basic_string< char > MString
Definition: maiatypes.h:55

◆ exchangeFsiData()

template<MInt nDim>
void RigidBodies< nDim >::exchangeFsiData

local(edge) bodies' parts of body forces are received from remote domains + remote bodies' parts of body forces is send to their home domains

Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de

Definition at line 821 of file rigidbodies.cpp.

821 {
822 TRACE();
823
824 // exchange local partial sum of the remote body force to the bodies home domain and add it
825 std::vector<MPI_Request> mpi_send_req(noHomeDomains(), MPI_REQUEST_NULL);
826 std::vector<MPI_Request> mpi_recv_req(noRemoteDomains(), MPI_REQUEST_NULL);
827
830
831 MInt bufSizePerBody = nDim * 2;
832 // allocate receive buffer per remote domain and create tmp sum buffer for each body
833 std::vector<std::vector<MFloat>> rcvBufferAll(noRemoteDomains);
834 MInt idx = 0;
835 for(const auto& [remoteDomain, bodies] : m_remoteDomainLocalBodies) {
836 rcvBufferAll[idx].resize(bodies.size() * bufSizePerBody);
837 idx++;
838 }
839
840 // receive predicted body state
841 idx = 0;
842 for(const auto& [remoteDomain, bodies] : m_remoteDomainLocalBodies) {
843 MPI_Irecv(rcvBufferAll[idx].data(), rcvBufferAll[idx].size(), maia::type_traits<MFloat>::mpiType(), remoteDomain, 2,
844 mpiComm(), &mpi_recv_req[idx], AT_, "recv predict");
845 idx++;
846 }
847
848 idx = 0;
849 MInt bodyCount = 0;
850 std::vector<std::vector<MFloat>> sendBufferAll(noHomeDomains);
851 // pack send buffer and send predicted body states to home domains
852 for(const auto& [homeDomain, bodies] : m_homeDomainRemoteBodies) {
853 // pack
854 auto& sendBuffer = sendBufferAll[idx];
855 sendBuffer.resize(bufSizePerBody * bodies.size());
856 bodyCount = 0;
857 for(const auto& body : bodies) {
858 for(MInt n = 0; n < nDim; n++) {
859 // when sending the FSI-Data to the homeDomain, we not only need the forces of the remoteBody, but also the
860 // forces of its associated dummy body, in case the remoteBody is self-mapped
861 if(hasAssociatedDummyBody(body)) {
862 a_bodyForce(body, n) += a_bodyForce(m_associatedDummyBodies[body], n);
864 }
865 sendBuffer[bodyCount + n] = a_bodyForce(body)[n];
866 sendBuffer[bodyCount + nDim + n] = a_bodyTorque(body)[n];
867 }
868 bodyCount += bufSizePerBody;
869 }
870 // send
871 MPI_Isend(sendBuffer.data(), sendBuffer.size(), maia::type_traits<MFloat>::mpiType(), homeDomain, 2, mpiComm(),
872 &mpi_send_req[idx], AT_, "send predict");
873 idx++;
874 }
875
876 // Wait for MPI exchange to complete
877 for(MInt i = 0; i < noHomeDomains; i++) {
878 MPI_Wait(&mpi_send_req[i], MPI_STATUS_IGNORE, AT_);
879 }
880
881 for(MInt i = 0; i < noRemoteDomains; i++) {
882 MPI_Wait(&mpi_recv_req[i], MPI_STATUS_IGNORE, AT_);
883 }
884
885 // add up required parts of remotely calculated surface force + torque
886 idx = 0;
887 for(const auto& [remoteDomain, bodies] : m_remoteDomainLocalBodies) {
888 bodyCount = 0;
889 for(const auto& body : bodies) {
890 for(MInt n = 0; n < nDim; n++) {
891 a_bodyForce(body)[n] += rcvBufferAll[idx][bodyCount + n];
892 a_bodyTorque(body)[n] += rcvBufferAll[idx][bodyCount + nDim + n];
893 }
894 bodyCount += bufSizePerBody;
895 }
896 idx++;
897 }
898
899 // Exchange FSI data for self-mapped Bodies
900 for(const auto& [body, dummyId] : m_associatedDummyBodies) {
901 for(MInt n = 0; n < nDim; n++) {
902 a_bodyForce(body, n) += a_bodyForce(dummyId, n);
903 a_bodyTorque(body, n) += a_bodyTorque(dummyId, n);
904 }
905 }
906}

◆ exchangeKinematicData()

template<MInt nDim>
void RigidBodies< nDim >::exchangeKinematicData

local(edge) bodies' kinematic data is send to remote domains + remote bodies' kinematic data is received from home domains

Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de

Definition at line 684 of file rigidbodies.cpp.

684 {
685 TRACE();
686
689
690 std::vector<MPI_Request> mpi_send_req(noRemoteDomains, MPI_REQUEST_NULL);
691 std::vector<MPI_Request> mpi_recv_req(noHomeDomains, MPI_REQUEST_NULL);
692
693 MInt bufSizePerBody = nDim * 3 + nRot * 2 + nQuat;
694 // allocate receive buffer per homeDomain
695 std::vector<std::vector<MFloat>> rcvBufferAll(noHomeDomains);
696 MInt idx = 0;
697 for(const auto& [homeDomain, bodies] : m_homeDomainRemoteBodies) {
698 rcvBufferAll[idx].resize(bodies.size() * bufSizePerBody);
699 idx++;
700 }
701
702 // receive predicted body state
703 idx = 0;
704 for(const auto& [homeDomain, bodies] : m_homeDomainRemoteBodies) {
705 MPI_Irecv(rcvBufferAll[idx].data(), rcvBufferAll[idx].size(), maia::type_traits<MFloat>::mpiType(), homeDomain, 2,
706 mpiComm(), &mpi_recv_req[idx], AT_, "recv predict");
707 idx++;
708 }
709
710 idx = 0;
711 MInt paraCount = 0;
712 MInt bodyCount = 0;
713 std::vector<std::vector<MFloat>> sendBufferAll(noRemoteDomains);
714 // pack send buffer and send predicted body states to all remote domains
715 for(const auto& [remoteDomain, bodies] : m_remoteDomainLocalBodies) {
716 // pack
717 auto& sendBuffer = sendBufferAll[idx];
718 sendBuffer.resize(bufSizePerBody * bodies.size());
719 bodyCount = 0;
720 for(const auto& body : bodies) {
721 paraCount = 0;
722 for(MInt n = 0; n < nDim; n++) {
723 sendBuffer[bodyCount + n] = a_bodyCenter(body, n);
724 // apply shift if periodic BCs are active
725 if(m_periodicBC) {
726 sendBuffer[bodyCount + n] += m_periodicShift[remoteDomain][body][n];
727 }
728 sendBuffer[bodyCount + nDim + n] = a_bodyVelocity(body, n);
729 sendBuffer[bodyCount + 2 * nDim + n] = a_bodyAcceleration(body, n);
730 }
731 paraCount += 3 * nDim;
732 for(MInt r = 0; r < nRot; r++) {
733 sendBuffer[bodyCount + paraCount + r] = a_angularVelocity(body, r);
734 sendBuffer[bodyCount + paraCount + nRot + r] = a_angularVelocityBody(body, r);
735 }
736 paraCount += 2 * nRot;
737 for(MInt q = 0; q < nQuat; q++) {
738 sendBuffer[bodyCount + paraCount + q] = a_bodyQuaternionT1(body, q);
739 }
740 bodyCount += bufSizePerBody;
741 }
742 // send
743 MPI_Isend(sendBuffer.data(), sendBuffer.size(), maia::type_traits<MFloat>::mpiType(), remoteDomain, 2, mpiComm(),
744 &mpi_send_req[idx], AT_, "send predict");
745 idx++;
746 }
747
748 // Wait for MPI exchange to complete
749 for(MInt i = 0; i < noRemoteDomains; i++) {
750 MPI_Wait(&mpi_send_req[i], MPI_STATUS_IGNORE, AT_);
751 }
752
753 for(MInt i = 0; i < noHomeDomains; i++) {
754 MPI_Wait(&mpi_recv_req[i], MPI_STATUS_IGNORE, AT_);
755 }
756
757 // unpack buffer -> same as packing
758 idx = 0;
759 for(const auto& [homeDomain, bodies] : m_homeDomainRemoteBodies) {
760 bodyCount = 0;
761 for(const auto& body : bodies) {
762 paraCount = 0;
763 for(MInt n = 0; n < nDim; n++) {
764 a_bodyCenter(body, n) = rcvBufferAll[idx][bodyCount + n];
765 a_bodyVelocity(body, n) = rcvBufferAll[idx][bodyCount + nDim + n];
766 a_bodyAcceleration(body, n) = rcvBufferAll[idx][bodyCount + nDim * 2 + n];
767 }
768 paraCount += 3 * nDim;
769 for(MInt r = 0; r < nRot; r++) {
770 a_angularVelocity(body, r) = rcvBufferAll[idx][bodyCount + paraCount + r];
771 a_angularVelocityBody(body, r) = rcvBufferAll[idx][bodyCount + paraCount + nRot + r];
772 }
773 paraCount += 2 * nRot;
774 for(MInt q = 0; q < nQuat; q++) {
775 a_bodyQuaternionT1(body, q) = rcvBufferAll[idx][bodyCount + paraCount + q];
776 }
777 bodyCount += bufSizePerBody;
778 }
779 idx++;
780 }
781
782 // Exchange kinematic Data for self-mapped Bodies
783 auto aDBCopy = m_associatedDummyBodies;
784 for(const auto& [body, dummyId] : aDBCopy) {
785 // if a remote body has a associated dummy body, but is not intersecting with a halo cell anymore -> delete dummy
786 // body
787 const MInt intersectingCellId =
788 grid().raw().intersectingWithHaloCells(&a_bodyCenter(body, 0), m_infoDiameter / 2.0, 0, true);
789 if(intersectingCellId == -1) {
790 deleteDummyBody(body);
791 continue;
792 }
793 for(MInt n = 0; n < nDim; n++) {
794 // periodic shift has to be updated?
795 m_periodicShift[domainId()][body][n] = calculatePeriodicShift(intersectingCellId, n);
796 a_bodyCenter(dummyId, n) = a_bodyCenter(body, n) + m_periodicShift[domainId()][body][n];
797 a_bodyVelocity(dummyId, n) = a_bodyVelocity(body, n);
798 a_bodyAcceleration(dummyId, n) = a_bodyAcceleration(body, n);
799 }
800 for(MInt r = 0; r < nRot; r++) {
801 a_angularVelocity(dummyId, r) = a_angularVelocity(body, r);
802 a_angularVelocityBody(dummyId, r) = a_angularVelocityBody(body, r);
803 }
804 for(MInt q = 0; q < nQuat; q++) {
805 a_bodyQuaternionT1(dummyId, q) = a_bodyQuaternionT1(body, q);
806 }
807 }
808}
MFloat & a_angularVelocity(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:588
MFloat & a_angularVelocityBody(const MInt bodyId, const MInt dim)
Definition: rigidbodies.h:591

◆ exchangeNeighborConnectionInfo()

template<MInt nDim>
void RigidBodies< nDim >::exchangeNeighborConnectionInfo

Definition at line 2562 of file rigidbodies.cpp.

2562 {
2563 TRACE();
2564 // for every remote body:
2565 // check every neighbordomain halo cells for intersection
2566 // contains globalIds
2567 std::vector<std::vector<MInt>> bodyIdsForRemoteDomain;
2568 std::vector<std::vector<MInt>> homeDomainIdsForRemoteDomain;
2569
2570 // contains localIds
2571 std::vector<std::vector<MInt>> bodyIdsForHomeDomain;
2572 std::vector<std::vector<MInt>> remoteDomainIdsForHomeDomain;
2573 std::vector<std::vector<std::array<MFloat, nDim>>> shiftForHomeDomain;
2574
2575 // body Ids + homeDomain Ids to send to remote domains
2576 bodyIdsForRemoteDomain.clear();
2577 bodyIdsForRemoteDomain.resize(noNeighborDomains());
2578
2579 homeDomainIdsForRemoteDomain.clear();
2580 homeDomainIdsForRemoteDomain.resize(noNeighborDomains());
2581
2582 // body Ids + remoteDomain Ids + shift to send to home domains
2583 bodyIdsForHomeDomain.clear();
2584 bodyIdsForHomeDomain.resize(noHomeDomains());
2585
2586 remoteDomainIdsForHomeDomain.clear();
2587 remoteDomainIdsForHomeDomain.resize(noHomeDomains());
2588
2589 shiftForHomeDomain.clear();
2590 shiftForHomeDomain.resize(noHomeDomains());
2591
2592 MInt count = 0;
2593 for(MInt i = 0; i < noNeighborDomains(); i++) {
2594 count = 0;
2595 for(const auto& [homeDomain, bodies] : m_homeDomainRemoteBodies) {
2596 for(const auto& body : bodies) {
2597 // check neighbor domain halo cells
2598 std::array<MFloat, nDim> center{};
2599 for(MInt n = 0; n < nDim; n++) {
2600 center[n] = a_bodyCenter(body, n);
2601 }
2602 const MInt intersectingCellId =
2603 grid().raw().intersectingWithHaloCells(center.data(), m_infoDiameter / 2.0, i, true);
2604 if(intersectingCellId != -1) {
2605 // data for new remote domain
2606 bodyIdsForRemoteDomain[i].push_back(getGlobalBodyId(body));
2607 homeDomainIdsForRemoteDomain[i].push_back(homeDomain);
2608
2609 // data for home domain
2610 const MInt remoteDomain = neighborDomain(i);
2611 // dont send body to its own home domain
2612 if(homeDomain == remoteDomain) {
2613 continue;
2614 }
2615 bodyIdsForHomeDomain[count].push_back(getGlobalBodyId(body));
2616 remoteDomainIdsForHomeDomain[count].push_back(remoteDomain);
2617 // shift
2618 std::array<MFloat, nDim> shiftVector{};
2619 for(MInt n = 0; n < nDim; n++) {
2620 const MFloat shift = calculatePeriodicShift(intersectingCellId, n);
2621 shiftVector[n] = shift;
2622 }
2623 shiftForHomeDomain[count].push_back(shiftVector);
2624 }
2625 }
2626 count++;
2627 }
2628 }
2629
2630 std::map<MInt, std::vector<MInt>> tmpRemoteMap;
2631
2632 exchangeNeighborNeighborRemote(bodyIdsForRemoteDomain, homeDomainIdsForRemoteDomain, tmpRemoteMap);
2633 exchangeNeighborNeighborHome(bodyIdsForHomeDomain, remoteDomainIdsForHomeDomain, shiftForHomeDomain);
2634
2635 // transfer tmp maps to member mappings
2636 for(auto [homeDomainId, remoteBodyIds] : tmpRemoteMap) {
2637 for(auto remoteBodyId : remoteBodyIds) {
2638 if(homeDomainId == domainId()) continue;
2639 const std::vector<MInt>* bodyIds = &(m_homeDomainRemoteBodies[homeDomainId]);
2640 // check if remote body is not in mapping yet
2641 if(!std::binary_search(bodyIds->begin(), bodyIds->end(), remoteBodyId)) {
2642 std::cout << "In Timestep " << globalTimeStep << "indirect Neighborstuff" << std::endl;
2643 // PseudoLocal, as just remote body for domain, but body is contained in collector
2644 // const MInt newPseudoLocalBodyId = getLocalBodyId(remoteBodyId);
2645 m_homeDomainRemoteBodies[homeDomainId].push_back(remoteBodyId);
2646 }
2647 }
2648 }
2649}
void exchangeNeighborNeighborRemote(std::vector< std::vector< MInt > > &bodyIdsForRemoteDomain, std::vector< std::vector< MInt > > &homeDomainIdsForRemoteDomain, std::map< MInt, std::vector< MInt > > &tmpRemoteMap)
void exchangeNeighborNeighborHome(std::vector< std::vector< MInt > > &bodyIdsForHomeDomain, std::vector< std::vector< MInt > > &remoteDomainIdsForHomeDomain, std::vector< std::vector< std::array< MFloat, nDim > > > &shiftForHomeDomain)

◆ exchangeNeighborNeighborHome()

template<MInt nDim>
void RigidBodies< nDim >::exchangeNeighborNeighborHome ( std::vector< std::vector< MInt > > &  bodyIdsForHomeDomain,
std::vector< std::vector< MInt > > &  remoteDomainIdsForHomeDomain,
std::vector< std::vector< std::array< MFloat, nDim > > > &  shiftForHomeDomain 
)

Definition at line 2717 of file rigidbodies.cpp.

2720 {
2721 TRACE();
2722 std::vector<MPI_Request> mpi_send_req(noHomeDomains(), MPI_REQUEST_NULL);
2723 std::vector<MPI_Request> mpi_recv_req(noRemoteDomains(), MPI_REQUEST_NULL);
2724
2725 // exchange buffer lengths to home domains
2726 std::vector<MInt> noToRecv(noRemoteDomains());
2727
2728 // body Id + remote domain id + shift
2729 const MInt bufSizePerBody = 1 + 1 + nDim;
2730 std::vector<MInt> noToSend(noHomeDomains());
2731 for(MInt n = 0; n < noHomeDomains(); n++) {
2732 noToSend[n] = bodyIdsForHomeDomain[n].size();
2733 }
2734
2735 exchangeBufferLengthsRemoteToHome(noToRecv, noToSend);
2736
2737 // create receive buffer
2738 std::vector<std::vector<MFloat>> recvBufferAll(noRemoteDomains());
2739 for(MInt n = 0; n < noRemoteDomains(); n++) {
2740 recvBufferAll[n].resize(noToRecv[n] * bufSizePerBody);
2741 }
2742
2743 // pack send buffer
2744 std::vector<std::vector<MFloat>> sendBufferAll(noHomeDomains());
2745 for(MInt n = 0; n < noHomeDomains(); n++) {
2746 sendBufferAll[n].resize(noToSend[n] * bufSizePerBody);
2747 for(MInt b = 0; b < noToSend[n]; b++) {
2748 sendBufferAll[n][b * bufSizePerBody] = bodyIdsForHomeDomain[n][b];
2749 sendBufferAll[n][b * bufSizePerBody + 1] = remoteDomainIdsForHomeDomain[n][b];
2750 for(MInt i = 0; i < nDim; i++) {
2751 sendBufferAll[n][b * bufSizePerBody + 2 + i] = shiftForHomeDomain[n][b][i];
2752 }
2753 }
2754 }
2755
2756 // recv
2757 MInt count = 0;
2758 for(const auto& [remoteDomain, bodies] : m_remoteDomainLocalBodies) {
2759 if(noToRecv[count]) {
2760 MPI_Irecv(recvBufferAll[count].data(), recvBufferAll[count].size(), maia::type_traits<MFloat>::mpiType(),
2761 remoteDomain, 2, mpiComm(), &mpi_recv_req[count], AT_, "recv neighbor-neighbor exchange");
2762 }
2763 count++;
2764 }
2765
2766 // send
2767 count = 0;
2768 for(const auto& [homeDomain, bodies] : m_homeDomainRemoteBodies) {
2769 if(noToSend[count]) {
2770 MPI_Isend(sendBufferAll[count].data(), sendBufferAll[count].size(), maia::type_traits<MFloat>::mpiType(),
2771 homeDomain, 2, mpiComm(), &mpi_send_req[count], AT_, "send neighbor-neighbor exchange");
2772 }
2773 count++;
2774 }
2775
2776 // wait for communication to finish
2777 for(MInt i = 0; i < noHomeDomains(); i++) {
2778 if(noToSend[i]) {
2779 MPI_Wait(&mpi_send_req[i], MPI_STATUS_IGNORE, AT_);
2780 }
2781 }
2782
2783 for(MInt i = 0; i < noRemoteDomains(); i++) {
2784 if(noToRecv[i]) {
2785 MPI_Wait(&mpi_recv_req[i], MPI_STATUS_IGNORE, AT_);
2786 }
2787 }
2788
2789 // unpack buffer
2790 const MInt currNoRemoteDomains = noRemoteDomains();
2791 for(MInt n = 0; n < currNoRemoteDomains; n++) {
2792 for(MInt b = 0; b < noToRecv[n]; b++) {
2793 const MInt localBodyId = getLocalBodyId((MInt)recvBufferAll[n][b * bufSizePerBody]);
2794 const MInt remoteDomainId = (MInt)recvBufferAll[n][b * bufSizePerBody + 1];
2795
2796 std::array<MFloat, nDim> shift{};
2797 for(MInt i = 0; i < nDim; i++) {
2798 shift[i] = recvBufferAll[n][b * bufSizePerBody + 2 + i];
2799 }
2800
2801 if(m_remoteDomainLocalBodies.find(remoteDomainId) != m_remoteDomainLocalBodies.end()) {
2802 std::vector<MInt>* bodyIds = &(m_remoteDomainLocalBodies[remoteDomainId]);
2803 if(std::binary_search(bodyIds->begin(), bodyIds->end(), localBodyId)) {
2804 continue;
2805 }
2806 }
2807 m_remoteDomainLocalBodies[remoteDomainId].push_back(localBodyId);
2808 m_periodicShift[remoteDomainId][localBodyId] = shift;
2809 }
2810 }
2811}
void exchangeBufferLengthsRemoteToHome(std::vector< MInt > &noToRecv, std::vector< MInt > &noToSend)

◆ exchangeNeighborNeighborRemote()

template<MInt nDim>
void RigidBodies< nDim >::exchangeNeighborNeighborRemote ( std::vector< std::vector< MInt > > &  bodyIdsForRemoteDomain,
std::vector< std::vector< MInt > > &  homeDomainIdsForRemoteDomain,
std::map< MInt, std::vector< MInt > > &  tmpRemoteMap 
)

Definition at line 2652 of file rigidbodies.cpp.

2654 {
2655 TRACE();
2656 std::vector<MPI_Request> mpi_send_req(noNeighborDomains(), MPI_REQUEST_NULL);
2657 std::vector<MPI_Request> mpi_recv_req(noNeighborDomains(), MPI_REQUEST_NULL);
2658
2659 // body Ids, home domain
2660 const MInt bufSizePerBody = 1 + 1;
2661 std::vector<MInt> noToSend(noNeighborDomains());
2662 for(MInt n = 0; n < noNeighborDomains(); n++) {
2663 noToSend[n] = bodyIdsForRemoteDomain[n].size();
2664 }
2665 // pack send buffer
2666 std::vector<std::vector<MInt>> sendBufferAll(noNeighborDomains());
2667 for(MInt n = 0; n < noNeighborDomains(); n++) {
2668 sendBufferAll[n].resize(noToSend[n] * bufSizePerBody);
2669 for(MInt b = 0; b < noToSend[n]; b++) {
2670 sendBufferAll[n][b * bufSizePerBody] = bodyIdsForRemoteDomain[n][b];
2671 sendBufferAll[n][b * bufSizePerBody + 1] = homeDomainIdsForRemoteDomain[n][b];
2672 }
2673 }
2674 // exchange buffer lengths
2675 std::vector<MInt> noToRecv(noNeighborDomains());
2676 exchangeBufferLengthsNeighbor(noToRecv, bodyIdsForRemoteDomain);
2677
2678 // create receive buffer
2679 std::vector<std::vector<MInt>> recvBufferAll(noNeighborDomains());
2680 for(MInt n = 0; n < noNeighborDomains(); n++) {
2681 recvBufferAll[n].resize(noToRecv[n] * bufSizePerBody);
2682 }
2683
2684 // recv
2685 for(MInt n = 0; n < noNeighborDomains(); n++) {
2686 MPI_Irecv(recvBufferAll[n].data(), recvBufferAll[n].size(), maia::type_traits<MInt>::mpiType(), neighborDomain(n),
2687 2, mpiComm(), &mpi_recv_req[n], AT_, "recv neighbor-neighbor exchange");
2688 }
2689
2690 // send
2691 for(MInt n = 0; n < noNeighborDomains(); n++) {
2692 MPI_Isend(sendBufferAll[n].data(), sendBufferAll[n].size(), maia::type_traits<MInt>::mpiType(), neighborDomain(n),
2693 2, mpiComm(), &mpi_send_req[n], AT_, "send neighbor-neighbor exchange");
2694 }
2695
2696 // wait for communication to finish
2697 for(MInt i = 0; i < noNeighborDomains(); i++) {
2698 MPI_Wait(&mpi_send_req[i], MPI_STATUS_IGNORE, AT_);
2699 MPI_Wait(&mpi_recv_req[i], MPI_STATUS_IGNORE, AT_);
2700 }
2701
2702 // unpack recv Buffer and fill remoteBodyHomeDomains
2703 for(MInt n = 0; n < noNeighborDomains(); n++) {
2704 for(MInt b = 0; b < noToRecv[n]; b++) {
2705 const MInt remoteBodyId = getLocalBodyId(recvBufferAll[n][b * bufSizePerBody]);
2706 const MInt homeDomain = recvBufferAll[n][b * bufSizePerBody + 1];
2707 const std::vector<MInt>* bodyIds = &(tmpRemoteMap[homeDomain]);
2708 // check if remote body is not in mappin yet
2709 if(!std::binary_search(bodyIds->begin(), bodyIds->end(), remoteBodyId)) {
2710 tmpRemoteMap[homeDomain].push_back(remoteBodyId);
2711 }
2712 }
2713 }
2714}

◆ exchangeTransferBodies()

template<MInt nDim>
void RigidBodies< nDim >::exchangeTransferBodies

sends them to new home domain + receives them from old home domain

puts them into local bodies list (comperable state as in find local bodies)

Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de

Definition at line 1598 of file rigidbodies.cpp.

1598 {
1599 TRACE();
1600 // transfer to new home domain
1601 // exchange no of transfer bodies to neighboring domains
1602 std::vector<MInt> noToRecv(noNeighborDomains());
1603 MInt totalBufferLength = 0;
1604 for(MInt i = 0; i < noNeighborDomains(); i++) {
1605 totalBufferLength += m_transferBodies[i].size();
1606 }
1607
1608 exchangeBufferLengthsNeighbors(noToRecv, totalBufferLength);
1609
1610 // send new home domain Id to every other home domain
1611 std::vector<MPI_Request> mpi_send_req(noNeighborDomains(), MPI_REQUEST_NULL);
1612 std::vector<MPI_Request> mpi_recv_req(noNeighborDomains(), MPI_REQUEST_NULL);
1613
1614 // create receive buffer
1615 std::vector<std::vector<MFloat>> rcvBufferAll(noNeighborDomains());
1616 MInt bufSizePerBody = 2;
1617
1618 for(MInt n = 0; n < noNeighborDomains(); n++) {
1619 rcvBufferAll[n].resize(MLong(noToRecv[n] * bufSizePerBody));
1620 }
1621
1622 // non-blocking receive
1623 for(MInt i = 0; i < noNeighborDomains(); i++) {
1624 if(!noToRecv[i]) {
1625 continue;
1626 }
1627
1628 MPI_Irecv(rcvBufferAll[i].data(), rcvBufferAll[i].size(), maia::type_traits<MFloat>::mpiType(), neighborDomain(i),
1629 2, mpiComm(), &mpi_recv_req[i], AT_, "recv predict");
1630 }
1631
1632 // create sendBuffer that is send to every domain
1633 MInt idx = 0;
1634 std::vector<MFloat> sendBufferAll(MLong(totalBufferLength * bufSizePerBody));
1635 std::list<std::pair<MInt, MInt>> localBodyRemoveList;
1636 for(MUint i = 0; i < m_transferBodies.size(); i++) {
1637 MUint domain = i;
1638 MUint newHomeDomain = neighborDomain(domain);
1639 for(const auto& body : m_transferBodies[i]) {
1640 sendBufferAll[MLong(idx * bufSizePerBody)] = (MFloat)getGlobalBodyId(body);
1641 sendBufferAll[idx * bufSizePerBody + 1] = (MFloat)newHomeDomain; // <- send new globalDomainId
1642 idx++;
1643
1644 auto it = std::find_if(localBodyRemoveList.cbegin(), localBodyRemoveList.cend(),
1645 [&body](const std::pair<MInt, MInt>& localB) { return localB.second == body; });
1646 if(it == localBodyRemoveList.cend()) {
1647 localBodyRemoveList.push_front(std::make_pair(newHomeDomain, body));
1648 }
1649 }
1650 }
1651
1652 // non-blocking send
1653 for(MInt i = 0; i < noNeighborDomains(); i++) {
1654 if(sendBufferAll.empty()) {
1655 continue;
1656 }
1657
1658 MPI_Isend(sendBufferAll.data(), sendBufferAll.size(), maia::type_traits<MFloat>::mpiType(), neighborDomain(i), 2,
1659 mpiComm(), &mpi_send_req[i], AT_, "send predict");
1660 }
1661
1662 // wait for communication to finish
1663 for(MInt i = 0; i < noNeighborDomains(); i++) {
1664 MPI_Wait(&mpi_send_req[i], MPI_STATUS_IGNORE, AT_);
1665 }
1666
1667 for(MInt i = 0; i < noNeighborDomains(); i++) {
1668 MPI_Wait(&mpi_recv_req[i], MPI_STATUS_IGNORE, AT_);
1669 }
1670
1671 // transferBodies change from local to remote status -> swap position in collector
1672 // only executed on sending domain
1673 // update mappings and collector accordingly
1674
1675 // Due to swapping, localIds in localBodyRemoveList might lose validity
1676 // This mapping starts as unity and is filled if a localBody becomes a swap target
1677 std::map<MInt, MInt> tmpMapping;
1678 for(const auto& [newDomainId, body] : localBodyRemoveList) {
1679 tmpMapping[body] = body;
1680 }
1681 for(const auto& [newDomainId, body] : localBodyRemoveList) {
1682 const MInt tmpCollectorId = tmpMapping[body];
1683 const MInt remoteBodyId = localToRemoteBody(tmpCollectorId, body, newDomainId);
1684
1685 // Fill mapping if one of the remaining localBodies was swapped
1686 for(auto& [newDomainId_, body_] : localBodyRemoveList) {
1687 if(body_ == remoteBodyId) {
1688 tmpMapping[body_] = tmpCollectorId;
1689 }
1690 }
1691 }
1692
1693 // unpack buffer
1694 // 1) Find all bodies, that are transfered to the current domain (remoteBodiesToLocal)
1695 // 2) Find all bodies, that changed there homeDomain in the same timestep, and update mapping accordingly, if relevant
1696 std::vector<std::pair<MInt, MInt>> remoteBodiesToLocal;
1697 std::vector<std::array<MInt, 2>> remoteBodiesNeighDomain;
1698 for(MInt n = 0; n < noNeighborDomains(); n++) {
1699 for(MInt b = 0; b < noToRecv[n]; b++) {
1700 MInt globalBodyId = MInt(rcvBufferAll[n][MLong(b * bufSizePerBody)]);
1701 MInt newHomeDomain = MInt(rcvBufferAll[n][MLong(b * bufSizePerBody + 1)]);
1702 const MInt localId = getLocalBodyId(globalBodyId);
1703
1704#ifdef RB_DEBUG
1705 m_debugFileStream << "received: " << globalBodyId << " with localId " << localId << " and new homeDomain "
1706 << newHomeDomain << "from " << neighborDomain(n) << std::endl;
1707#endif
1708
1709 if(newHomeDomain == domainId()) {
1710 if(localId == -1) {
1711 mTerm(1, AT_,
1712 "ERROR: Body " + std::to_string(globalBodyId) + " has not been on domain " + std::to_string(domainId())
1713 + " before !");
1714 }
1715 MInt oldHomeDomainId = neighborDomain(n);
1716 remoteBodiesToLocal.emplace_back(oldHomeDomainId, globalBodyId);
1717 } else if(localId != -1) {
1718 remoteBodiesNeighDomain.push_back({newHomeDomain, globalBodyId});
1719 }
1720 }
1721 }
1722
1723 // 3) make received bodies local
1724 // If body was previously remote on domain, it gets now local -> change position of body in collector of
1725 // receiving domain (append to local bodies)
1726 for(MUint i = 0; i < remoteBodiesToLocal.size(); i++) {
1727 if(m_noRemoteBodies <= 0) {
1728 mTerm(1, AT_, "Domain: " + std::to_string(domainId()) + " has no remote bodies that can change to local status!");
1729 }
1730 MInt oldHomeDomainId = remoteBodiesToLocal[i].first;
1731 MInt globalId = remoteBodiesToLocal[i].second;
1732 MInt localId = getLocalBodyId(globalId);
1733
1734 const MInt newIdx = m_noLocalBodies;
1735
1736#ifdef RB_DEBUG
1737 m_debugFileStream << "B localId: " << localId << " globalId " << globalId << " newIdx " << newIdx
1738 << " globalIdNewIdx: " << getGlobalBodyId(newIdx) << " oldHomeDomain " << oldHomeDomainId
1739 << std::endl;
1740#endif
1741
1742 if(noConnectingBodies() > 1) {
1743 m_bodies.swap(localId, newIdx);
1744 iter_swap(m_globalBodyIds.begin() + localId, m_globalBodyIds.begin() + newIdx);
1745 }
1748
1749 // we just append to local bodies and therefore do not need to update this mapping
1750 m_remoteDomainLocalBodies[oldHomeDomainId].push_back(newIdx);
1751
1752 // update localIds in mapping
1753 std::map<MInt, std::vector<MInt>> oldMapping(m_homeDomainRemoteBodies);
1754 for(auto& [domain, bodies] : oldMapping) {
1755 // first delete the new local Body from Remote Body mapping -> body is now on current domain
1756 for(const MInt& body : bodies) {
1757 if(body == localId) {
1758#ifdef RB_DEBUG
1759 m_debugFileStream << "delete body " << body << " domain " << domain << std::endl;
1760#endif
1761 std::vector<MInt>* c = &m_homeDomainRemoteBodies[domain];
1762 c->erase(std::remove(c->begin(), c->end(), localId), c->end());
1763 }
1764 }
1765 // when making a local body remote, all the ids of the remote bodies, that have a lower id than the new local body
1766 // have to be modified. This is done in a second loop to prevent accidental deletion of a body
1767 // if you want to remove local id 1, local id 0 is raised to local id 1
1768 for(MInt& body : m_homeDomainRemoteBodies[domain]) {
1769 if(body < localId) {
1770 body++;
1771 }
1772 }
1773 }
1774 }
1775
1776#ifdef RB_DEBUG
1778#endif
1779
1780 // 4) now after all localBodies and the corresponding remoteDomains are updated
1781 // we potentielly need to update the homeDomain of our remote Bodies
1782 // search in mapping to find body and update new HomeDomain
1783 MBool found = false;
1784 for(const auto& arr : remoteBodiesNeighDomain) {
1785 const MInt newHomeDomain = arr[0];
1786 const MInt globalId = arr[1];
1787
1788 const MInt NewLocalId = getLocalBodyId(globalId);
1789
1790 for(const auto& [domain, bodies] : m_homeDomainRemoteBodies) {
1791 if(domain == domainId()) continue;
1792 for(const auto& bodyId : bodies) {
1793 if(getGlobalBodyId(bodyId) == globalId) {
1794 found = true;
1795 // a remote Body was transfered to a new homedomain, update:
1796 if(domain != newHomeDomain) {
1797 std::vector<MInt>* c = &m_homeDomainRemoteBodies[domain];
1798 c->erase(std::remove(c->begin(), c->end(), NewLocalId), c->end());
1799
1800 m_homeDomainRemoteBodies[newHomeDomain].push_back(NewLocalId);
1801 break;
1802 }
1803#ifdef RB_DEBUG
1805 << "something went wrong, domain should be diff from newHomeDomain in remoteBodiesNeighDomain! "
1806 << "Domain is " << domain << " newHomeDomain is " << newHomeDomain << std::endl;
1807#endif
1808 }
1809 }
1810 if(found) break;
1811 }
1812 }
1813#ifdef RB_DEBUG
1814 m_debugFileStream << "end of exchange: " << std::endl;
1816#endif
1817}
void exchangeBufferLengthsNeighbors(std::vector< MInt > &noToRecv, const MInt noToSend)
exchange of Buffer lengths all to all in direct neighborhood
std::vector< std::vector< MInt > > m_transferBodies
Definition: rigidbodies.h:288
MInt localToRemoteBody(const MInt collectorId, const MInt oldBodyId, const MInt domain)
this function transforms a localBody to a remoteBody on the current domain, necessary if a body cross...

◆ finalizeAdaptation()

template<MInt nDim>
void RigidBodies< nDim >::finalizeAdaptation ( )
inlineoverridevirtual

Reimplemented from Solver.

Definition at line 121 of file rigidbodies.h.

121{};

◆ finalizeInitSolver()

template<MInt nDim>
void RigidBodies< nDim >::finalizeInitSolver ( )
inlineoverridevirtual

Implements Solver.

Definition at line 89 of file rigidbodies.h.

89{};

◆ findClosestPointEllipsoid() [1/3]

MFloat RigidBodies< 3 >::findClosestPointEllipsoid ( const MFloat *const  relPos,
const MInt  bodyId 
)
private

Here, the point is given in the body frame of reference

Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
coordinates[in]Point from which the distance is calculated
bodyId[in]Body id to which the distance is calculated
Returns
Closest distance to the ellipsoid

Definition at line 3749 of file rigidbodies.cpp.

3749 {
3750 TRACE();
3751 std::ignore = bodyId;
3752 MFloat e[3] = {a_bodyRadii(bodyId, 0), a_bodyRadii(bodyId, 1), a_bodyRadii(bodyId, 2)};
3753 MFloat y[3] = {relPos[0], relPos[1], relPos[2]};
3754 MFloat x[3]{};
3755
3756 // Determine reflections for y to the first octant.
3757 bool reflect[3];
3758 int i;
3759 int j;
3760 for(i = 0; i < 3; ++i) {
3761 reflect[i] = (y[i] < .0);
3762 }
3763
3764 // Determine the axis order for decreasing extents.
3765 int permute[3];
3766 if(e[0] < e[1]) {
3767 if(e[2] < e[0]) {
3768 permute[0] = 1;
3769 permute[1] = 0;
3770 permute[2] = 2;
3771 } else if(e[2] < e[1]) {
3772 permute[0] = 1;
3773 permute[1] = 2;
3774 permute[2] = 0;
3775 } else {
3776 permute[0] = 2;
3777 permute[1] = 1;
3778 permute[2] = 0;
3779 }
3780 } else {
3781 if(e[2] < e[1]) {
3782 permute[0] = 0;
3783 permute[1] = 1;
3784 permute[2] = 2;
3785 } else if(e[2] < e[0]) {
3786 permute[0] = 0;
3787 permute[1] = 2;
3788 permute[2] = 1;
3789 } else {
3790 permute[0] = 2;
3791 permute[1] = 0;
3792 permute[2] = 1;
3793 }
3794 }
3795
3796 std::array<MInt, 3> invpermute{};
3797 for(i = 0; i < 3; ++i) {
3798 invpermute[permute[i]] = i;
3799 }
3800
3801 std::array<MFloat, 3> locE{};
3802 std::array<MFloat, 3> locY{};
3803 for(i = 0; i < 3; ++i) {
3804 j = permute[i];
3805 locE[i] = e[j];
3806 locY[i] = y[j];
3807 if(reflect[j]) {
3808 locY[i] = -locY[i];
3809 }
3810 }
3811
3812 std::array<MFloat, 3> locX{};
3813 for(i = 0; i < 3; ++i) {
3814 ASSERT(!(locY[i] < F0), "");
3815 locY[i] = mMax(MFloatEps, locY[i]); // guarantee non-zero entries
3816 }
3817 MFloat distance = distancePointEllipsoid(locE, locY, locX);
3818
3819 // Restore the axis order and reflections.
3820 for(i = 0; i < 3; ++i) {
3821 j = invpermute[i];
3822 if(reflect[i]) {
3823 locX[j] = -locX[j];
3824 }
3825 x[i] = locX[j];
3826 }
3827
3828 std::ignore = x;
3829
3830 if((POW2(y[0] / e[0]) + POW2(y[1] / e[1]) + POW2(y[2] / e[2])) < F1) {
3831 distance = -distance;
3832 }
3833
3834 return distance;
3835}
MFloat distancePointEllipsoid(const std::array< MFloat, 3 > e, const std::array< MFloat, 3 > y, std::array< MFloat, 3 > x)
Calculates the closest distance between a given point and a ellipsoid in 3D.

◆ findClosestPointEllipsoid() [2/3]

template<MInt nDim>
MFloat RigidBodies< nDim >::findClosestPointEllipsoid ( const MFloat *const  relPos,
const MInt  bodyId 
)
private

◆ findClosestPointEllipsoid() [3/3]

MFloat RigidBodies< 2 >::findClosestPointEllipsoid ( const MFloat * const  ,
const  MInt 
)
private

Here, the point is given in the body frame of reference

Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
coordinates[in]Point from which the distance is calculated
bodyId[in]Body id to which the distance is calculated
Returns
Closest distance to the ellipsoid

Definition at line 3731 of file rigidbodies.cpp.

3731 {
3732 std::cerr << "Find Ellipse closest point 2D needs to be implemented! " << std::endl;
3733 return 0.0;
3734}

◆ findLocalBodies()

template<MInt nDim>
void RigidBodies< nDim >::findLocalBodies
Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de

Definition at line 1469 of file rigidbodies.cpp.

1469 {
1470 TRACE();
1471
1472 // loop over all bodies initial bodies
1473 for(MInt globalBodyId = 0; globalBodyId < noEmbeddedBodies(); globalBodyId++) {
1474 std::array<MFloat, nDim> tmpCenter{};
1475 for(MInt n = 0; n < nDim; n++) {
1476 if(m_restart) {
1477 tmpCenter[n] = m_bResFile.bodyCenter(globalBodyId, n);
1478 } else {
1479 tmpCenter[n] = m_initialBodyCenters[globalBodyId * nDim + n];
1480 }
1481 }
1482 MBool insideLocalBbox = grid().raw().pointInLocalBoundingBox(tmpCenter.data());
1483 if(insideLocalBbox) {
1484 MInt localPCellId = grid().raw().findContainingPartitionCell(tmpCenter.data(), -1, nullptr);
1485 if(localPCellId != -1) {
1486 m_globalBodyIds.emplace_back(globalBodyId);
1488 }
1489 }
1490 }
1491}

◆ findTransferBodies()

template<MInt nDim>
void RigidBodies< nDim >::findTransferBodies
  • removes them from local & edge body list & body mapping
Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de

Definition at line 1562 of file rigidbodies.cpp.

1562 {
1563 TRACE();
1564 m_transferBodies.clear();
1566
1567 for(MInt i = 0; i < noNeighborDomains(); i++) {
1568 /* 1) if local bodies center is contained in a neighbor domains halo cell
1569 ** move local body -> transfer body
1570 */
1571 for(const MInt& bodyId : m_remoteDomainLocalBodies[neighborDomain(i)]) {
1572 MBool outside = -1 != grid().raw().findContainingHaloCell(&a_bodyCenter(bodyId, 0), -1, i, true, nullptr);
1573 if(outside) {
1574 // Already get new index of body to be transfered in collector in transferBodies
1575 m_transferBodies[i].push_back(bodyId);
1576#ifdef RB_DEBUG
1577 m_debugFileStream << "Found transfer body with globalId " << getGlobalBodyId(bodyId)
1578 << " will be sent to domain " << i << std::endl;
1579#endif
1580 }
1581 }
1582 }
1583}

◆ geometry()

template<MInt nDim>
Geom & RigidBodies< nDim >::geometry ( ) const
inline

Definition at line 82 of file rigidbodies.h.

82{ return *m_geometry; }

◆ getAngularVelocity()

template<MInt nDim>
void RigidBodies< nDim >::getAngularVelocity ( const MInt  bodyId,
std::array< MFloat, nRot > &  angularVelocity 
)
inline

Definition at line 594 of file rigidbodies.h.

594 {
595 for(MInt n = 0; n < nRot; n++) {
596 angularVelocity[n] = a_angularVelocityT1(bodyId, n);
597 }
598 }

◆ getBodyProperties()

template<MInt nDim>
MFloat * RigidBodies< nDim >::getBodyProperties ( MInt  returnMode,
MInt  bodyId 
)

◆ getDistance()

template<MInt nDim>
template<MInt bodyType>
MFloat RigidBodies< nDim >::getDistance ( const MFloat *const  coordinates,
const MInt  bodyId 
)
inline
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
coordinates[in]Point from which the distance is calculated
bodyId[in]Body id to which the distance is calculated
Returns
Closest distance to the body

Definition at line 384 of file rigidbodies.h.

384 {
385 ASSERT(bodyId > -1 && bodyId < noCollectorBodies(), "BodyId " << bodyId);
386 MFloat dist = F1;
387 if(bodyType == Shapes::Sphere) {
388 dist = getDistanceSphere(coordinates, bodyId);
389 } else if(bodyType == Shapes::Piston) {
390 dist = getDistancePiston(coordinates, bodyId);
391 } else if(bodyType == Shapes::Cube) {
392 dist = getDistanceCube(coordinates, bodyId);
393 } else if(bodyType == Shapes::Ellipsoid) {
394 dist = getDistanceEllipsoid(coordinates, bodyId);
395 } else {
396 mTerm(1, AT_, "BodyType not implemented!");
397 }
398
399 return dist;
400 }
MFloat getDistancePiston(const MFloat *coordinates, const MInt bodyId)
Calculates the closest distance between a given point and a piston.
MFloat getDistanceEllipsoid(const MFloat *coordinates, const MInt bodyId)
Calculates the closest distance between a given point and a ellipsoid.
MFloat getDistanceCube(const MFloat *coordinates, const MInt bodyId)
Calculates the closest distance between a given point and a cube.
MFloat getDistanceSphere(const MFloat *coordinates, const MInt bodyId)
Calculates the closest distance between a given point and a sphere.

◆ getDistanceCube()

template<MInt nDim>
MFloat RigidBodies< nDim >::getDistanceCube ( const MFloat coordinates,
const MInt  bodyId 
)
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
coordinates[in]Point from which the distance is calculated
bodyId[in]Body id to which the distance is calculated
Returns
Closest distance to the cube

Definition at line 3673 of file rigidbodies.cpp.

3673 {
3674 TRACE();
3675 const MFloat x = coordinates[0] - a_bodyCenter(bodyId, 0);
3676 const MFloat y = coordinates[1] - a_bodyCenter(bodyId, 1);
3677
3678 const MFloat lim_x = std::max(x, -x);
3679 const MFloat lim_y = std::max(y, -y);
3680
3681 MFloat dist = std::max(lim_x, lim_y);
3682
3683 IF_CONSTEXPR(nDim == 3) {
3684 const MFloat z = coordinates[2] - a_bodyCenter(bodyId, 2);
3685 const MFloat lim_z = std::max(z, -z);
3686 dist = std::max(dist, lim_z);
3687 }
3688
3689 return dist - a_bodyRadius(bodyId);
3690}

◆ getDistanceEllipsoid()

template<MInt nDim>
MFloat RigidBodies< nDim >::getDistanceEllipsoid ( const MFloat coordinates,
const MInt  bodyId 
)
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
coordinates[in]Point from which the distance is calculated
bodyId[in]Body id to which the distance is calculated
Returns
Closest distance to the ellipsoid

Definition at line 3703 of file rigidbodies.cpp.

3703 {
3704 TRACE();
3705 MFloat relPos[nDim]{};
3706 for(MInt n = 0; n < nDim; n++) {
3707 relPos[n] = coordinates[n] - a_bodyCenter(bodyId, n);
3708 }
3709
3710 const MFloat* const bodyQuaternion = &a_bodyQuaternionT1(bodyId, 0);
3711 transformToBodyFrame(bodyQuaternion, relPos);
3712
3713 MFloat dist = findClosestPointEllipsoid(&relPos[0], bodyId);
3714
3715 return dist;
3716}
MFloat findClosestPointEllipsoid(const MFloat *const relPos, const MInt bodyId)

◆ getDistancePiston()

template<MInt nDim>
MFloat RigidBodies< nDim >::getDistancePiston ( const MFloat coordinates,
const MInt  bodyId 
)
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
coordinates[in]Point from which the distance is calculated
bodyId[in]Body id to which the distance is calculated
Returns
Closest distance to the piston

Definition at line 3650 of file rigidbodies.cpp.

3650 {
3651 TRACE();
3652 const MFloat x = coordinates[0] - a_bodyCenter(bodyId, 0);
3653 const MFloat y = coordinates[1] - a_bodyCenter(bodyId, 1);
3654 const MFloat z = coordinates[2] - a_bodyCenter(bodyId, 2);
3655
3656 MFloat dist_cylinder = sqrt(POW2(x) + POW2(z)) - a_bodyRadius(bodyId);
3657 MFloat dist_caps = -y - m_bodyHeight / 2;
3658
3659 return std::max(dist_cylinder, dist_caps);
3660}
MFloat m_bodyHeight
Definition: rigidbodies.h:157

◆ getDistanceSphere()

template<MInt nDim>
MFloat RigidBodies< nDim >::getDistanceSphere ( const MFloat coordinates,
const MInt  bodyId 
)
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
coordinates[in]Point from which the distance is calculated
bodyId[in]Body id to which the distance is calculated
Returns
Closest distance to the sphere

Definition at line 3627 of file rigidbodies.cpp.

3627 {
3628 TRACE();
3629 MFloat dist = .0;
3630 for(MInt n = 0; n < nDim; n++) {
3631 dist += POW2(coordinates[n] - a_bodyCenter(bodyId, n));
3632 }
3633
3634 dist = sqrt(dist) - a_bodyRadius(bodyId);
3635
3636 return dist;
3637}

◆ getDomainOffset()

template<MInt nDim>
MLong RigidBodies< nDim >::getDomainOffset

Definition at line 1311 of file rigidbodies.cpp.

1311 {
1312 TRACE();
1313
1314 std::vector<MInt> noLocalBodiesPerPartition(noDomains());
1315 exchangeBufferLengthsAllToAll(noLocalBodiesPerPartition, m_noLocalBodies);
1316
1317 MLong offset{};
1318 for(MInt i = 0; i < domainId(); i++) {
1319 offset += noLocalBodiesPerPartition[i];
1320 }
1321
1322 return offset;
1323}

◆ getGlobalBodyId()

template<MInt nDim>
MInt RigidBodies< nDim >::getGlobalBodyId ( MInt  localBodyId)
inline

Definition at line 415 of file rigidbodies.h.

415{ return m_globalBodyIds.at(localBodyId); }

◆ getHeatFlux()

template<MInt nDim>
MFloat RigidBodies< nDim >::getHeatFlux ( const MInt  bodyId)
inline

Definition at line 491 of file rigidbodies.h.

491{ return m_bodies.bodyHeatFlux(bodyId); }

◆ getLocalBodyId()

template<MInt nDim>
MInt RigidBodies< nDim >::getLocalBodyId ( MInt  globalBodyId)
inline

Definition at line 408 of file rigidbodies.h.

408 {
409 std::vector<MInt>::iterator itr = std::find(m_globalBodyIds.begin(), m_globalBodyIds.end(), globalBodyId);
410 if(itr != m_globalBodyIds.cend()) {
411 return std::distance(m_globalBodyIds.begin(), itr);
412 }
413 return -1;
414 }

◆ getVelocity()

template<MInt nDim>
void RigidBodies< nDim >::getVelocity ( const MInt  bodyId,
std::array< MFloat, nDim > &  velocity 
)
inline

Definition at line 483 of file rigidbodies.h.

483 {
484 for(MInt n = 0; n < nDim; n++) {
485 velocity[n] = m_bodies.bodyVelocity(bodyId, n);
486 }
487 }

◆ globBBox()

template<MInt nDim>
MFloat RigidBodies< nDim >::globBBox ( MInt  n)
inlineprivate

Definition at line 272 of file rigidbodies.h.

272{ return grid().raw().globalBoundingBox()[n]; }

◆ hasAssociatedDummyBody()

template<MInt nDim>
MBool RigidBodies< nDim >::hasAssociatedDummyBody ( const MInt  bodyId) const
inline

Definition at line 431 of file rigidbodies.h.

431 {
432 if(m_associatedDummyBodies.empty()) {
433 return false;
434 }
435 return m_associatedDummyBodies.find(bodyId) != m_associatedDummyBodies.end();
436 }

◆ incrementHeatFlux()

template<MInt nDim>
void RigidBodies< nDim >::incrementHeatFlux ( const MInt  bodyId,
MFloat  heatflux 
)
inline

Definition at line 489 of file rigidbodies.h.

489{ m_bodies.bodyHeatFlux(bodyId) += heatflux; }

◆ initBodyData()

template<MInt nDim>
void RigidBodies< nDim >::initBodyData
private
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de

Definition at line 261 of file rigidbodies.cpp.

261 {
262 TRACE();
263
264 if(m_restart) {
266 }
267
269
270 m_bodies.reset(m_maxNoBodies);
271
272 // Create Mapping
273 for(MInt i = 0; i < noNeighborDomains(); i++) {
274 MInt globDomain = neighborDomain(i);
275 m_remoteDomainLocalBodies[globDomain] = std::vector<MInt>();
276 m_homeDomainRemoteBodies[globDomain] = std::vector<MInt>();
277 }
278
280
281 if(m_noLocalBodies == 0 && !m_restart) return;
282
283 // Init bodyRadius and bodyRadii via bodyRadius
284 if(!m_initBodyRadius.empty()) {
285 // If only one radius is given, use for all bodies
286 if(m_initBodyRadius.size() == 1) {
287 const MFloat defaultRadius = m_initBodyRadius[0];
288 std::fill_n(&a_bodyRadius(0), m_noLocalBodies, defaultRadius);
289 std::fill_n(&a_bodyRadii(0, 0), m_noLocalBodies * nDim, defaultRadius);
290 } else {
291 for(MUint bodyId = 0; bodyId < m_initBodyRadius.size(); bodyId++) {
293 std::fill_n(&a_bodyRadii(bodyId, 0), nDim, m_initBodyRadius[getGlobalBodyId(bodyId)]);
294 }
295 }
296 }
297
298 // Init bodyRadii via bodyRadii
299 if(!m_initBodyRadii.empty()) {
300 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
301 // If only one set of radii is given, use for all bodies
302 if(m_initBodyRadii.size() == nDim) {
303 for(MInt n = 0; n < nDim; n++) {
304 a_bodyRadii(bodyId, n) = m_initBodyRadii[n];
305 }
306 } else {
307 for(MInt n = 0; n < nDim; n++) {
308 a_bodyRadii(bodyId, n) = m_initBodyRadii[getGlobalBodyId(bodyId) * nDim + n];
309 }
310 }
311 }
312 }
313
314 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
315 for(MInt n = 0; n < nRot; n++) {
316 a_angularVelocityT1(bodyId, n) = 0.0;
317 a_angularAccelerationT1(bodyId, n) = 0.0;
318 }
319 }
320
321 if(!m_forcedMotion) {
322 if(m_initBodyDensityRatios.size() > 1) {
323 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
325 }
326 } else if(m_initBodyDensityRatios.size() == 1) {
327 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
329 }
330 } else {
331 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
332 a_bodyDensityRatio(bodyId) = 1.0;
333 }
334 }
335
336 // Init rotational data
337 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
338 for(MInt n = 0; n < nRot; n++) {
339 a_bodyInertia(bodyId, n) = 1.0;
340 a_angularVelocityT1B2(bodyId, n) = 0.0;
341 a_angularVelocityBodyT1(bodyId, n) = 0.0;
342 a_angularVelocityBodyT1B2(bodyId, n) = 0.0;
343 a_angularAccelerationBody(bodyId, n) = 0.0;
344 a_torqueT1(bodyId, n) = 0.0;
345 }
346 }
347
348 // Init bodyQuaternion and moment of inertia
349 IF_CONSTEXPR(nDim == 3) {
350 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
351 for(MInt n = 0; n < nQuat - 1; n++) {
352 a_bodyQuaternionT1B2(bodyId, n) = 0;
353 a_bodyQuaternionT1(bodyId, n) = 0;
354 }
355 a_bodyQuaternionT1B2(bodyId, nQuat - 1) = 1.0;
356 a_bodyQuaternionT1(bodyId, nQuat - 1) = 1.0;
357 a_bodyInertia(bodyId, 0) =
358 (POW2(a_bodyRadii(bodyId, 1)) + POW2(a_bodyRadii(bodyId, 2))) / 5.0 * a_bodyMass(bodyId);
359 a_bodyInertia(bodyId, 1) =
360 (POW2(a_bodyRadii(bodyId, 0)) + POW2(a_bodyRadii(bodyId, 2))) / 5.0 * a_bodyMass(bodyId);
361 a_bodyInertia(bodyId, 2) =
362 (POW2(a_bodyRadii(bodyId, 0)) + POW2(a_bodyRadii(bodyId, 1))) / 5.0 * a_bodyMass(bodyId);
363 }
364 }
365 }
366
367 if(m_restart) {
369 // Init remaining values
370 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
371 a_bodyHeatFlux(bodyId) = 0.0;
372 const MInt tmpGlobalId = getGlobalBodyId(bodyId);
373
374 a_bodyTemperature(bodyId) = m_bResFile.bodyTemperature(tmpGlobalId);
375 for(MInt n = 0; n < nDim; n++) {
376 a_bodyCenter(bodyId, n) = m_bResFile.bodyCenter(tmpGlobalId, n);
377 a_bodyVelocity(bodyId, n) = m_bResFile.bodyVelocity(tmpGlobalId, n);
378 a_bodyAcceleration(bodyId, n) = m_bResFile.bodyAcceleration(tmpGlobalId, n);
379 }
380 for(MInt r = 0; r < nRot; r++) {
381 a_angularVelocityBodyT1B2(bodyId, r) = m_bResFile.angularVelocityBodyT1B2(tmpGlobalId, r);
382 a_angularAccelerationBody(bodyId, r) = m_bResFile.angularAccelerationBody(tmpGlobalId, r);
383 }
384 for(MInt q = 0; q < nQuat; q++) {
385 a_bodyQuaternionT1B2(bodyId, q) = m_bResFile.bodyQuaternionT1B2(tmpGlobalId, q);
386 a_bodyQuaternionT1(bodyId, q) = m_bResFile.bodyQuaternionT1(tmpGlobalId, q);
387 }
388 }
389 } else {
390 // Set init body values
391 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
392 for(MInt n = 0; n < nDim; n++) {
393 a_bodyCenter(bodyId, n) = m_initialBodyCenters[getGlobalBodyId(bodyId) * nDim + n];
394 a_bodyVelocity(bodyId, n) = 0.0;
395 a_bodyAcceleration(bodyId, n) = 0.0;
396 a_bodyForce(bodyId, n) = 0.0;
397 }
398 a_bodyTemperature(bodyId) = 1.0;
399 a_bodyHeatFlux(bodyId) = 0.0;
400 }
401 }
402
403 // Transfer initialValues to *Dt1 fields.
404 if(!m_forcedMotion) {
406 }
407}
void loadBodyRestartFile()
Loads restart file for the RigidBodies solver.
std::vector< MFloat > m_initBodyDensityRatios
Definition: rigidbodies.h:190
std::vector< MFloat > m_initBodyRadius
Definition: rigidbodies.h:192
void loadBodiesSizeAndPosition()
loadind no of embedded bodies and it's position from restart file
MInt m_maxNoBodies
Definition: rigidbodies.h:167
void findLocalBodies()
searches in all initial Bodies for local bodies
void advanceBodies()
Copy the body data for time t to t-1 to prepare the next timestep.
std::vector< MFloat > m_initBodyRadii
Definition: rigidbodies.h:194

◆ initBodyLog()

template<MInt nDim>
void RigidBodies< nDim >::initBodyLog
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de

Definition at line 416 of file rigidbodies.cpp.

416 {
417 TRACE();
418
419 // delete output file if it already exists
420 MBool body_exists = fileExists("bodies.log");
421 MBool angBody_exists = fileExists("angvel.log");
422
423 if(body_exists) {
424 std::remove("bodies.log");
425 m_log << "replaced body log";
426 }
427
428 if(angBody_exists) {
429 std::remove("angvel.log");
430 m_log << "replaced angular body log";
431 }
432
433 m_log.open("bodies.log", std::ios::app);
434 m_anglog.open("angvel.log", std::ios::app);
435
436 if(!m_logBodyData) {
437 if(!domainId()) {
438 std::stringstream logEntry;
439 std::stringstream logEntryAng;
440
441 logEntry << ">>> enable body log by using: 'logBodyData = true' "
442 << "\n";
443 logEntryAng << ">>> enable body log by using: 'logBodyData = true' "
444 << "\n";
445
446 m_log << logEntry.str();
447 m_log.close();
448
449 m_anglog << logEntryAng.str();
450 m_anglog.close();
451 }
452 return;
453 }
454
455 MString delimiter = " ";
456 m_logVars.insert(m_logVars.end(), {"t", "body", "x", "y", "z", "u", "v", "w", "c_x", "c_y", "c_z"});
457
458 m_logAngVars.insert(m_logAngVars.end(),
459 {"t", "body", "ang_vel_x", "ang_vel_y", "ang_vel_z", "tourque_x", "tourque_y", "tourque_z"});
460
461 IF_CONSTEXPR(nDim == 2) {
462 std::vector<MString> removeList{"z", "w", "c_z"};
463 std::vector<MString> removeListAng{"ang_vel_z", "tourque_z"};
464 for(const MString& r : removeList) {
465 m_logVars.erase(std::remove(m_logVars.begin(), m_logVars.end(), r), m_logVars.end());
466 }
467
468 for(const MString& r : removeListAng) {
469 m_logAngVars.erase(std::remove(m_logAngVars.begin(), m_logAngVars.end(), r), m_logAngVars.end());
470 }
471 }
472
473 for(const MString& var : m_logVars) {
474 m_log << var << delimiter;
475 }
476
477 for(const MString& var : m_logAngVars) {
478 m_anglog << var << delimiter;
479 }
480
481 m_log << "\n";
482 m_anglog << "\n";
483
484 m_log.close();
485 m_anglog.close();
486}
std::ofstream m_log
Definition: rigidbodies.h:320
MBool m_logBodyData
Definition: rigidbodies.h:317
std::vector< MString > m_logVars
Definition: rigidbodies.h:179
std::vector< MString > m_logAngVars
Definition: rigidbodies.h:180
MBool fileExists(const MString &fileName)
Returns true if the file fileName exists, false otherwise.
Definition: functions.cpp:73

◆ initGridProperties()

template<MInt nDim>
void RigidBodies< nDim >::initGridProperties

Definition at line 1494 of file rigidbodies.cpp.

1494 {
1495 TRACE();
1496 // Counting periodic directions
1497 MInt periodic = 0;
1498 for(MInt n = 0; n < nDim; n++) {
1499 m_globDomainLength[n] = globBBox(nDim + n) - globBBox(n);
1500 periodic += grid().raw().periodicCartesianDir(n);
1501 }
1502
1503 if(periodic) {
1504 m_periodicBC = true;
1505
1506 constexpr MFloat eps = 1e-9;
1507 MBool domainIsCube = true;
1508 for(MInt n = 0; n < nDim; n++) {
1509 domainIsCube = domainIsCube && (m_globDomainLength[0] - m_globDomainLength[n]) < eps;
1510 }
1511
1512 if(!domainIsCube) {
1513 std::cerr << "\033[0;31m Warning:\033[0m Domain is not a cube - periodic BCs only work on cube domains"
1514 << std::endl;
1515 }
1516 }
1517
1519}
void updateMaxLevel(MInt newMaxLevel)
Definition: rigidbodies.h:341

◆ initRemoteDummyBodyData()

template<MInt nDim>
void RigidBodies< nDim >::initRemoteDummyBodyData ( const MInt  bodyId)
Author
Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de
Parameters
[in]bodyId,localBodyIdof the remoteBody

Definition at line 2357 of file rigidbodies.cpp.

2357 {
2358 TRACE();
2359
2360 const MInt dummyId = m_associatedDummyBodies[bodyId];
2361 if(isRemoteBody(bodyId)) {
2362 // Exchange kinematic Data for remote self-mapped Bodies
2363 for(MInt n = 0; n < nDim; n++) {
2364 a_bodyCenter(dummyId, n) = a_bodyCenter(bodyId, n) + m_periodicShift[domainId()][bodyId][n];
2365 a_bodyVelocity(dummyId, n) = a_bodyVelocity(bodyId, n);
2366 a_bodyAcceleration(dummyId, n) = a_bodyAcceleration(bodyId, n);
2367 a_bodyForce(dummyId, n) = -a_bodyForce(bodyId, n);
2368 a_bodyTorque(dummyId, n) = a_bodyTorque(bodyId, n);
2369 }
2370 for(MInt r = 0; r < nRot; r++) {
2371 a_angularVelocity(dummyId, r) = a_angularVelocity(bodyId, r);
2372 a_angularVelocityBody(dummyId, r) = a_angularVelocityBody(bodyId, r);
2373 }
2374 for(MInt q = 0; q < nQuat; q++) {
2375 a_bodyQuaternionT1(dummyId, q) = a_bodyQuaternionT1(bodyId, q);
2376 }
2377 } else {
2378#ifdef RB_DEBUG
2379 m_debugFileStream << "Something went wrong, body with localId: " << bodyId
2380 << " is not a remoteBody -> dummyBodyData cannot be initialized!" << std::endl;
2381#endif
2382 return;
2383 }
2384}
MBool isRemoteBody(MInt bodyId)
Definition: rigidbodies.h:419

◆ initSolver()

template<MInt nDim>
void RigidBodies< nDim >::initSolver ( )
inlineoverridevirtual

Implements Solver.

Definition at line 88 of file rigidbodies.h.

88{};

◆ initTimers()

template<MInt nDim>
void RigidBodies< nDim >::initTimers
private

Definition at line 88 of file rigidbodies.cpp.

88 {
89 TRACE();
90
91 // Create timer group and coupler timer, and start the timer
92 NEW_TIMER_GROUP_NOCREATE(m_timers[Timers::TimerGroup], "RigidBodies");
93 NEW_TIMER_NOCREATE(m_timers[Timers::Class], "Total object lifetime", m_timers[Timers::TimerGroup]);
94 RECORD_TIMER_START(m_timers[Timers::Class]);
95
96 // Create and start constructor timer
97 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Constructor], "Constructor", m_timers[Timers::Class]);
98 RECORD_TIMER_START(m_timers[Timers::Constructor]);
99
100 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SolutionStep], "Solution Step", m_timers[Timers::Class]);
101
102 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Predict], "Predict", m_timers[Timers::SolutionStep]);
103 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Correct], "Correct", m_timers[Timers::SolutionStep]);
104
105 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Communication], "Communication", m_timers[Timers::SolutionStep]);
106 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::UpdateCommunication], "Update Communication", m_timers[Timers::SolutionStep]);
107}

◆ isLocalBody()

template<MInt nDim>
MBool RigidBodies< nDim >::isLocalBody ( MInt  bodyId)
inline

Definition at line 417 of file rigidbodies.h.

417{ return bodyId < m_noLocalBodies; }

◆ isRemoteBody()

template<MInt nDim>
MBool RigidBodies< nDim >::isRemoteBody ( MInt  bodyId)
inline

Definition at line 419 of file rigidbodies.h.

419{ return bodyId >= m_noLocalBodies; }

◆ linSpace()

template<MInt nDim>
void RigidBodies< nDim >::linSpace ( MFloat  start,
MFloat  end,
MInt  num,
std::vector< MFloat > &  linspaced 
)

◆ loadBodiesSizeAndPosition()

template<MInt nDim>
void RigidBodies< nDim >::loadBodiesSizeAndPosition
Author
Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de

Definition at line 4088 of file rigidbodies.cpp.

4088 {
4089 TRACE();
4090
4091 using namespace maia::parallel_io;
4092
4093 std::stringstream fileNameStream;
4094 fileNameStream.clear();
4095
4096 fileNameStream << m_restartDir << "restartBodyData_" << m_restartTimeStep;
4097 fileNameStream << ParallelIo::fileExt();
4098
4099 const MString fileName = fileNameStream.str();
4100
4101 if(domainId() == 0) {
4102 std::cerr << "loading noBodies and positions " << fileNameStream.str() << " at " << globalTimeStep << "...";
4103 }
4104
4105 ParallelIo parallelIo(fileName, PIO_READ, mpiComm());
4106
4107 parallelIo.setOffset(1, 0);
4108 parallelIo.readScalar(&m_noEmbeddedBodies, "noBodies");
4110
4112 m_bResFile.append(noEmbeddedBodies());
4113 parallelIo.setOffset(noEmbeddedBodies() * nDim, 0);
4114 parallelIo.readArray(&m_bResFile.bodyCenter(0, 0), "bodyCenter");
4115
4116 if(domainId() == 0) {
4117 std::cerr << "reading noBodies and initial position from restart-file done" << std::endl;
4118 }
4119}
MString m_restartDir
Definition: rigidbodies.h:178
MInt m_restartTimeStep
Definition: rigidbodies.h:171
PARALLELIO_DEFAULT_BACKEND ParallelIo
Definition: parallelio.h:292

◆ loadBodyRestartFile()

template<MInt nDim>
void RigidBodies< nDim >::loadBodyRestartFile
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de

Definition at line 4127 of file rigidbodies.cpp.

4127 {
4128 TRACE();
4129
4130 using namespace maia::parallel_io;
4131
4132 std::stringstream fileNameStream;
4133 fileNameStream.clear();
4134
4135 fileNameStream << m_restartDir << "restartBodyData_" << m_restartTimeStep;
4136 fileNameStream << ParallelIo::fileExt();
4137
4138 const MString fileName = fileNameStream.str();
4139
4140 const MLong DOF = noEmbeddedBodies();
4141 const MLong DOF_TRANS = DOF * nDim;
4142 const MLong DOF_ROT = DOF * nDim;
4143 const MLong DOF_QUAT = DOF * (nDim + 1);
4144
4145 if(domainId() == 0) {
4146 std::cerr << "loading body restart file " << fileNameStream.str() << " at " << globalTimeStep << "...";
4147 }
4148
4149 ParallelIo parallelIo(fileName, PIO_READ, mpiComm());
4150
4151 parallelIo.setOffset(DOF, 0);
4152 parallelIo.readArray(&m_bResFile.bodyTemperature(0), "bodyTemperature");
4153
4154 parallelIo.setOffset(DOF_TRANS, 0);
4155 parallelIo.readArray(&m_bResFile.bodyVelocity(0, 0), "bodyVelocity");
4156 parallelIo.readArray(&m_bResFile.bodyAcceleration(0, 0), "bodyAcceleration");
4157
4158 parallelIo.setOffset(DOF_ROT, 0);
4159 parallelIo.readArray(&m_bResFile.angularVelocityBodyT1B2(0, 0), "angularVelocityBodyT1B2");
4160 parallelIo.readArray(&m_bResFile.angularAccelerationBody(0, 0), "angularAccelerationBody");
4161
4162 parallelIo.setOffset(DOF_QUAT, 0);
4163 parallelIo.readArray(&m_bResFile.bodyQuaternionT1B2(0, 0), "bodyQuaternionT1B2");
4164 parallelIo.readArray(&m_bResFile.bodyQuaternionT1(0, 0), "bodyQuaternionT1");
4165
4166 if(domainId() == 0) {
4167 std::cerr << "reading bodyRestartFile done" << std::endl;
4168 }
4169}

◆ localToRemoteBody()

template<MInt nDim>
MInt RigidBodies< nDim >::localToRemoteBody ( const MInt  collectorId,
const MInt  oldBodyId,
const MInt  domain 
)
private
Author
Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de
Parameters
[in]oldBodyIdis the Id the body had when it was a localBody
[in]domainthe new homeDomain of the body

Definition at line 2395 of file rigidbodies.cpp.

2395 {
2396 TRACE();
2397
2398 if(m_noLocalBodies <= 0) {
2399 mTerm(1, AT_, "Domain: " + std::to_string(domainId()) + " has no local bodies that can change to remote status!");
2400 }
2401
2402 const MInt newIdx = m_noLocalBodies - 1;
2403
2404 if(hasAssociatedDummyBody(oldBodyId)) {
2405 deleteDummyBody(oldBodyId);
2406 }
2407
2408 // If more than one localBody in collector -> do swap, else not necessary to swap, just mark local body as remote
2409 if(noConnectingBodies() > 0) {
2410 m_bodies.swap(collectorId, newIdx);
2411 iter_swap(m_globalBodyIds.begin() + collectorId, m_globalBodyIds.begin() + newIdx);
2412 }
2413
2416
2417 /* Delete from local Bodies, now a remote Body
2418 / Not every local Body has a corresponding remoteDomain, therefore, we need to check each body, already
2419 / contained in the mapping. A local body can potentielly be remote to multiple domains
2420 / -> iterate over all domains in mapping
2421 */
2422 for(MInt n = 0; n < noNeighborDomains(); n++) {
2423 MInt globDomain = neighborDomain(n);
2424 std::vector<MInt>* bodies = &m_remoteDomainLocalBodies[globDomain];
2425
2426 // Check if the swapped body is in the mapping
2427 auto swappedIt = std::find(bodies->begin(), bodies->end(), newIdx);
2428 if(swappedIt != bodies->end()) {
2429 // Swapped body is in the mapping, delete its old entry and keep the other for the swapped Body
2430 bodies->erase(std::remove(bodies->begin(), bodies->end(), newIdx), bodies->end());
2431 } else {
2432 // Swapped body is NOT in the mapping, just delete the entry of the old local body
2433 bodies->erase(std::remove(bodies->begin(), bodies->end(), collectorId), bodies->end());
2434 }
2435
2436 if(hasAssociatedDummyBody(newIdx)) {
2437 m_associatedDummyBodies.erase(newIdx);
2438 m_associatedDummyBodies[newIdx] = collectorId;
2439 }
2440 }
2441
2442 m_homeDomainRemoteBodies[domain].push_back(newIdx);
2443
2444 return newIdx;
2445}

◆ logBodyData()

template<MInt nDim>
void RigidBodies< nDim >::logBodyData
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de

Definition at line 947 of file rigidbodies.cpp.

947 {
948 TRACE();
949 if(!m_logBodyData || !(globalTimeStep % m_intervalBodyLog == 0)) return;
950 // mpi_gatherv body data to write file with domain 0
951 // bodyId + pos + vel + acc + ang_vel + torque
952 const MInt bufSizePerBody = 1 + nDim * 5;
953 std::vector<MFloat> sendBuffer(MLong(bufSizePerBody * m_noLocalBodies));
954 for(MInt i = 0; i < m_noLocalBodies; i++) {
955 MInt bodyId = i;
956 sendBuffer[MLong(i * bufSizePerBody)] = (MFloat)bodyId;
957 for(MInt n = 0; n < nDim; n++) {
958 sendBuffer[i * bufSizePerBody + 1 + n] = a_bodyCenter(bodyId, n);
959 sendBuffer[i * bufSizePerBody + 1 + 1 * nDim + n] = a_bodyVelocity(bodyId, n);
960 sendBuffer[i * bufSizePerBody + 1 + 2 * nDim + n] = a_bodyAcceleration(bodyId, n);
961 sendBuffer[i * bufSizePerBody + 1 + 3 * nDim + n] = a_angularVelocity(bodyId, n);
962 sendBuffer[i * bufSizePerBody + 1 + 4 * nDim + n] = a_bodyTorque(bodyId, n);
963 }
964 }
965
966 std::vector<MInt> noToRecv(noDomains());
967 const MUint noToSend = sendBuffer.size();
968 exchangeBufferLengthsAllToRoot(noToRecv, noToSend);
969
970 MInt count = 0;
971 std::vector<MInt> displacements(noDomains());
972 for(MInt n = 0; n < noDomains(); n++) {
973 // noToRecv[n] *= bufSizePerBody;
974 displacements[n] = count;
975 count += noToRecv[n];
976 }
977
978 // create receive buffer
979 std::vector<MFloat> rcvBuffer(MLong(m_noEmbeddedBodies * bufSizePerBody));
980 MPI_Gatherv(sendBuffer.data(), sendBuffer.size(), maia::type_traits<MFloat>::mpiType(), rcvBuffer.data(),
981 noToRecv.data(), displacements.data(), maia::type_traits<MFloat>::mpiType(), 0, mpiComm(), AT_, "send",
982 "recv");
983
984 if(domainId() != 0) return;
985
986 MString delimiter = " ";
987 std::stringstream logEntry;
988 std::stringstream logEntryAng;
989
990 for(MInt b = 0; b < m_noEmbeddedBodies; b++) {
991 MInt bodyId = (MInt)rcvBuffer[MLong(b * bufSizePerBody)];
992
993 logEntry << globalTimeStep << delimiter;
994 logEntry << bodyId << delimiter;
995
996 logEntryAng << globalTimeStep << delimiter;
997 logEntryAng << bodyId << delimiter;
998
999 std::array<MFloat, nDim> center{};
1000 std::array<MFloat, nDim> velocity{};
1001 std::array<MFloat, nDim> acceleration{};
1002 std::array<MFloat, nDim> ang_vel{};
1003 std::array<MFloat, nDim> torque{};
1004
1005 for(MInt n = 0; n < nDim; n++) {
1006 center[n] = rcvBuffer[b * bufSizePerBody + 1 + n];
1007 velocity[n] = rcvBuffer[b * bufSizePerBody + 1 + nDim + n];
1008 acceleration[n] = rcvBuffer[b * bufSizePerBody + 1 + 2 * nDim + n];
1009 ang_vel[n] = rcvBuffer[b * bufSizePerBody + 1 + 3 * nDim + n];
1010 torque[n] = rcvBuffer[b * bufSizePerBody + 1 + 4 * nDim + n];
1011 }
1012
1013 // bodies log
1014 for(MInt n = 0; n < nDim; n++) {
1015 logEntry << std::scientific << center[n] << delimiter;
1016 }
1017
1018 for(MInt n = 0; n < nDim; n++) {
1019 logEntry << std::scientific << velocity[n] << delimiter;
1020 }
1021
1022 for(MInt n = 0; n < nDim; n++) {
1023 logEntry << std::scientific << acceleration[n] << delimiter;
1024 }
1025
1026 // angvel log
1027 for(MInt n = 0; n < nDim; n++) {
1028 logEntryAng << std::scientific << ang_vel[n] << delimiter;
1029 }
1030
1031 for(MInt n = 0; n < nDim; n++) {
1032 logEntryAng << std::scientific << torque[n] << delimiter;
1033 }
1034
1035 logEntry << "\n";
1036 logEntryAng << "\n";
1037 }
1038
1039 m_log.open("bodies.log", std::ios::app);
1040 m_log << logEntry.str();
1041 m_log.close();
1042
1043 m_anglog.open("angvel.log", std::ios::app);
1044 m_anglog << logEntryAng.str();
1045 m_anglog.close();
1046}
MInt m_intervalBodyLog
Definition: rigidbodies.h:319
void exchangeBufferLengthsAllToRoot(std::vector< MInt > &noToRecv, const MInt noToSend)
exchange of Buffer lengths all to root
int MPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gatherv

◆ mpiComm()

template<MInt nDim>
MPI_Comm RigidBodies< nDim >::mpiComm ( ) const
inline

Definition at line 103 of file rigidbodies.h.

103{ return MPI_COMM_WORLD; }

◆ noCollectorBodies()

template<MInt nDim>
MInt RigidBodies< nDim >::noCollectorBodies ( ) const
inline

Definition at line 425 of file rigidbodies.h.

◆ noConnectingBodies()

template<MInt nDim>
MInt RigidBodies< nDim >::noConnectingBodies ( ) const
inline

Definition at line 423 of file rigidbodies.h.

◆ noEmbeddedBodies()

template<MInt nDim>
MInt RigidBodies< nDim >::noEmbeddedBodies ( ) const
inline

Definition at line 421 of file rigidbodies.h.

421{ return m_noEmbeddedBodies; }

◆ noHomeDomains()

template<MInt nDim>
MInt RigidBodies< nDim >::noHomeDomains ( ) const
inline

Definition at line 427 of file rigidbodies.h.

427{ return m_homeDomainRemoteBodies.size(); }

◆ noInternalCells()

template<MInt nDim>
MInt RigidBodies< nDim >::noInternalCells ( ) const
inlineoverridevirtual

Implements Solver.

Definition at line 94 of file rigidbodies.h.

94{ return 0; };

◆ noRemoteDomains()

template<MInt nDim>
MInt RigidBodies< nDim >::noRemoteDomains ( ) const
inline

Definition at line 429 of file rigidbodies.h.

429{ return m_remoteDomainLocalBodies.size(); }

◆ outputDir()

template<MInt nDim>
MString RigidBodies< nDim >::outputDir ( ) const
inlineprivate

Definition at line 266 of file rigidbodies.h.

266{ return m_outputDir; }
MString m_outputDir
Definition: rigidbodies.h:164

◆ postAdaptation()

template<MInt nDim>
void RigidBodies< nDim >::postAdaptation ( )
inlineoverridevirtual

Reimplemented from Solver.

Definition at line 120 of file rigidbodies.h.

120{};

◆ postTimeStep()

template<MInt nDim>
void RigidBodies< nDim >::postTimeStep ( )
inlinevirtual

Implements Solver.

Definition at line 86 of file rigidbodies.h.

86{};

◆ predictorStep()

template<MInt nDim>
void RigidBodies< nDim >::predictorStep
private
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de

Definition at line 1066 of file rigidbodies.cpp.

1066 {
1067 TRACE();
1068
1069 const MFloat dt = m_timestep;
1070
1071 if(m_translation) {
1072 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
1073 // Translational values
1074 for(MInt n = 0; n < nDim; n++) {
1075 // Determine acceleration
1076 a_bodyAcceleration(bodyId, n) = a_bodyAccelerationOld(bodyId, n);
1077
1078 // Determine velocities
1079 a_bodyVelocity(bodyId, n) = a_bodyVelocityOld(bodyId, n)
1080 + 0.5 * dt * (a_bodyAcceleration(bodyId, n) + a_bodyAccelerationOld(bodyId, n));
1081
1082 // Determine position
1083 a_bodyCenter(bodyId, n) =
1084 a_bodyCenterOld(bodyId, n) + dt * a_bodyVelocityOld(bodyId, n)
1085 + 0.25 * POW2(dt) * (a_bodyAcceleration(bodyId, n) + a_bodyAccelerationOld(bodyId, n));
1086 }
1087
1088 if(m_rotation) {
1089 predictRotation(bodyId);
1090 }
1091
1092 // Scalar values
1093 // Determine temperature
1094 a_bodyTemperature(bodyId) =
1095 a_bodyTemperatureOld(bodyId) + dt * a_bodyHeatFlux(bodyId) / (m_bodyHeatCapacity * a_bodyMass(bodyId));
1096 }
1097 } else {
1098 if(m_rotation) {
1099 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
1100 predictRotation(bodyId);
1101 }
1102 }
1103 }
1104}
void predictRotation(const MInt bodyId)

◆ predictRotation() [1/3]

void RigidBodies< 3 >::predictRotation ( const MInt  bodyId)
inlineprivate

For reference, see L.J.H. Seelen et al., Improved bodyQuaternion-based integration scheme for rigid body motion

Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
bodyIdBody id for which the prediction is performed

Definition at line 2925 of file rigidbodies.cpp.

2925 {
2926 const MFloat dt = m_timestep;
2927
2928 MFloat angularVelocityBodyT3B4[nRot]{};
2929 // Advance angular velocity from time n+1/2 to time n+3/4
2930 for(MInt n = 0; n < nRot; n++) {
2931 angularVelocityBodyT3B4[n] =
2932 a_angularVelocityBodyT1B2(bodyId, n) + 0.25 * dt * a_angularAccelerationBody(bodyId, n);
2933 }
2934 // Transform angular velocity to world frame
2935 MFloat angularVelocityT3B4[nRot]{};
2936 transformToWorldFrame(&a_bodyQuaternionT1B2(bodyId, 0), angularVelocityBodyT3B4, angularVelocityT3B4);
2937
2938 // Advance bodyQuaternion from time n+1/2 to time n+1
2939 advanceQuaternion(angularVelocityT3B4, dt / 2, &a_bodyQuaternionT1B2(bodyId, 0), &a_bodyQuaternionT1(bodyId, 0));
2940
2941 // Advance angular velocity from time n+1/2 to time n+3/4
2942 for(MInt n = 0; n < nRot; n++) {
2943 a_angularVelocityBodyT1(bodyId, n) =
2944 a_angularVelocityBodyT1B2(bodyId, n) + 0.5 * dt * a_angularAccelerationBody(bodyId, n);
2945 }
2947 &a_angularVelocityT1(bodyId, 0));
2948}

◆ predictRotation() [2/3]

template<MInt nDim>
void RigidBodies< nDim >::predictRotation ( const MInt  bodyId)
inlineprivate

◆ predictRotation() [3/3]

void RigidBodies< 2 >::predictRotation ( const  MInt)
inlineprivate
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
MIntBody id for wich the prediction is performed

Definition at line 2958 of file rigidbodies.cpp.

2958 {
2959 std::cerr << "predictRotation: No implementation for 2D!" << std::endl;
2960}

◆ prepareAdaptation() [1/2]

template<MInt nDim>
void RigidBodies< nDim >::prepareAdaptation ( )
inlineoverridevirtual

Reimplemented from Solver.

Definition at line 111 of file rigidbodies.h.

111{};

◆ prepareAdaptation() [2/2]

template<MInt nDim>
void RigidBodies< nDim >::prepareAdaptation ( std::vector< std::vector< MFloat > > &  NotUsedsensors,
std::vector< MFloat > &  NotUsedsensorWeight,
std::vector< std::bitset< 64 > > &  NotUsedsensorCellFlag,
std::vector< MInt > &  NotUsedsensorSolverId 
)
inlineoverride

Definition at line 107 of file rigidbodies.h.

110 {};

◆ prepareRestart()

template<MInt nDim>
MBool RigidBodies< nDim >::prepareRestart ( MBool  ,
MBool  
)
inlineoverridevirtual

Reimplemented from Solver.

Definition at line 96 of file rigidbodies.h.

96{ return writeRestart; }

◆ preTimeStep()

template<MInt nDim>
void RigidBodies< nDim >::preTimeStep
overridevirtual
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de

Implements Solver.

Definition at line 587 of file rigidbodies.cpp.

587 {
588 m_newTimeStep = true;
589}
MBool m_newTimeStep
Definition: rigidbodies.h:148

◆ printBodyDomainConnections()

template<MInt nDim>
void RigidBodies< nDim >::printBodyDomainConnections
Author
Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de

Definition at line 2820 of file rigidbodies.cpp.

2820 {
2821 TRACE();
2822
2823 std::vector<MString> sBodies;
2824 MInt idx = 0;
2825
2826 sBodies.emplace_back("");
2827 if(m_noLocalBodies != 0) {
2828 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
2829 sBodies[idx] += std::to_string(bodyId) + " ";
2830 }
2831 }
2832 idx++;
2833
2834 sBodies.emplace_back("");
2835 if(m_noRemoteBodies > 0) {
2836 for(MInt bodyId = m_noLocalBodies; bodyId < noConnectingBodies(); bodyId++) {
2837 sBodies[idx] += std::to_string(bodyId) + " ";
2838 }
2839 }
2840 idx++;
2841
2842 sBodies.emplace_back("");
2843 if(m_noDummyBodies > 0) {
2844 for(MInt bodyId = noConnectingBodies(); bodyId < noCollectorBodies(); bodyId++) {
2845 sBodies[idx] += std::to_string(bodyId) + " ";
2846 }
2847 }
2848 idx++;
2849
2850 sBodies.emplace_back("");
2851 if(!m_transferBodies.empty()) {
2852 for(MInt i = 0; i < noNeighborDomains(); i++) {
2853 if(!m_transferBodies[i].empty()) {
2854 MString sTmp;
2855 for(MInt body : m_transferBodies[i]) {
2856 sTmp += std::to_string(body) + " ";
2857 }
2858 sBodies[idx] += std::to_string(neighborDomain(i)) + ": [" + sTmp + " ] | ";
2859 }
2860 }
2861 }
2862 idx++;
2863
2864 sBodies.emplace_back("");
2865 if(!m_globalBodyIds.empty()) {
2866 for(MUint localBodyId = 0; localBodyId < m_globalBodyIds.size(); localBodyId++) {
2867 sBodies[idx] +=
2868 "| localId: " + std::to_string(localBodyId) + " globalId: " + std::to_string(m_globalBodyIds[localBodyId]);
2869 }
2870 }
2871 idx++;
2872
2873 sBodies.emplace_back("");
2874 if(!m_remoteDomainLocalBodies.empty()) {
2875 for(const auto& [domain, bodies] : m_remoteDomainLocalBodies) {
2876 for(const auto& body : bodies) {
2877 sBodies[idx] += std::string(" ") + "[" + std::to_string(domain) + ", " + std::to_string(body) + "]";
2878 }
2879 }
2880 }
2881 idx++;
2882
2883 sBodies.emplace_back("");
2884 if(!m_homeDomainRemoteBodies.empty()) {
2885 for(const auto& [domain, bodies] : m_homeDomainRemoteBodies) {
2886 for(const auto& body : bodies) {
2887 sBodies[idx] += std::string(" ") + "[" + std::to_string(domain) + ", " + std::to_string(body) + "]";
2888 }
2889 }
2890 }
2891 idx++;
2892
2893 sBodies.emplace_back("");
2894 if(!m_associatedDummyBodies.empty()) {
2895 for(const auto& [body, dummy] : m_associatedDummyBodies) {
2896 sBodies[idx] += std::string(" ") + "[" + std::to_string(body) + ", " + std::to_string(dummy) + "]";
2897 }
2898 }
2899 idx++;
2900
2901 m_debugFileStream << "--------------BODY INFO for domain: " << domainId() << "---------------------" << std::endl
2902 << " contains bodyIds [ " << sBodies[0] << " ]" << std::endl
2903 << " contains remoteBodyIds [ " << sBodies[1] << " ]" << std::endl
2904 << " contains dummyBodyIds [ " << sBodies[2] << " ]" << std::endl
2905 << " has transferBodies for neighbourdomain " << sBodies[3] << std::endl
2906 << " has following pairings: " << sBodies[4] << std::endl
2907 << " remote domain - local body pairings: " << sBodies[5] << std::endl
2908 << " home domain - remote body pairings: " << sBodies[6] << std::endl
2909 << " body - associated dummy pairings: " << sBodies[7] << std::endl
2910 << " collector has capacity: " << m_bodies.capacity() << " and size " << m_bodies.size()
2911 << " MaxNoBodies is " << m_maxNoBodies << std::endl;
2912}

◆ printScalingVariables()

template<MInt nDim>
void RigidBodies< nDim >::printScalingVariables

Definition at line 489 of file rigidbodies.cpp.

489 {
490 TRACE();
491
492 std::map<MString, MInt> scalingVars;
493 scalingVars["localBodies"] = m_noLocalBodies;
494 scalingVars["connectedBodies"] = noConnectingBodies();
495 scalingVars["neighborDomains"] = noNeighborDomains();
496
497 std::vector<MInt> recvBuffer;
498 recvBuffer.resize(noDomains());
499 for(const auto& [name, value] : scalingVars) {
501 0, mpiComm(), AT_, "send", "recv");
502
503 if(!domainId()) {
504 // average
505 MFloat avgValue = 0;
506 avgValue = std::accumulate(recvBuffer.begin(), recvBuffer.end(), avgValue);
507 avgValue /= noDomains();
508 std::cout << "Average " + name + " per Domain are: " << avgValue << std::endl;
509
510 // maximum
511 const MInt maxValue = *std::max_element(recvBuffer.begin(), recvBuffer.end());
512 std::cout << "Max " + name + " per Domain are: " << maxValue << std::endl;
513
514 // minimum
515 const MInt minValue = *std::min_element(recvBuffer.begin(), recvBuffer.end());
516 std::cout << "Min " + name + " per Domain are: " << minValue << std::endl;
517 }
518 }
519}
int MPI_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gather

◆ quaternionToEuler()

template<MInt nDim>
void RigidBodies< nDim >::quaternionToEuler ( const MFloat *const  quaternion,
MFloat *const  angles 
)
inlineprivate
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
[in]quaternionquaternion describing the rotational state
[out]anglesEuler angles describing the rotational state

Definition at line 3199 of file rigidbodies.cpp.

3199 {
3200 TRACE();
3201 const MFloat& x = quaternion[0];
3202 const MFloat& y = quaternion[1];
3203 const MFloat& z = quaternion[2];
3204 const MFloat& w = quaternion[3];
3205
3206 MFloat& roll = angles[0];
3207 MFloat& pitch = angles[1];
3208 MFloat& yaw = angles[2];
3209
3210 // roll (x-axis rotation)
3211 MFloat sinr_cosp = 2 * (w * x + y * z);
3212 MFloat cosr_cosp = 1 - 2 * (x * x + y * y);
3213 roll = std::atan2(sinr_cosp, cosr_cosp);
3214
3215 // pitch (y-axis rotation)
3216 MFloat sinp = 2 * (w * y - z * x);
3217 if(std::abs(sinp) >= 1) {
3218 pitch = std::copysign(M_PI / 2, sinp); // use 90 degrees if out of range
3219 } else {
3220 pitch = std::asin(sinp);
3221 }
3222
3223 // yaw (z-axis rotation)
3224 MFloat siny_cosp = 2 * (w * z + x * y);
3225 MFloat cosy_cosp = 1 - 2 * (y * y + z * z);
3226 yaw = std::atan2(siny_cosp, cosy_cosp);
3227}

◆ readProperties()

template<MInt nDim>
void RigidBodies< nDim >::readProperties
private
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..de

Definition at line 158 of file rigidbodies.cpp.

158 {
159 TRACE();
160
161 m_outputDir = "./";
162 m_outputDir = Context::getSolverProperty<MString>("outputDir", m_solverId, AT_, &m_outputDir);
163
164 m_printKineticEnergy = false;
165 Context::getSolverProperty<MBool>("printKineticEnergy", m_solverId, AT_, &m_printKineticEnergy);
166
168 m_intervalBodyLog = Context::getSolverProperty<MInt>("intervalBodyLog", m_solverId, AT_, &m_intervalBodyLog);
169
170 // restart related Properties
171 m_restart = false;
172 m_restart = Context::getSolverProperty<MBool>("restartFile", m_solverId, AT_, &m_restart);
173
175 m_restartTimeStep = Context::getSolverProperty<MInt>("restartTimeStep", m_solverId, AT_, &m_restartTimeStep);
176
177 m_restartDir = Context::getSolverProperty<MString>("restartDir", m_solverId, AT_, &m_outputDir);
178
179 m_bodyCenterInitMethod = "POINT";
181 Context::getSolverProperty<MString>("bodyCenterInitMethod", m_solverId, AT_, &m_bodyCenterInitMethod);
182
183 if(!m_restart) {
184 if(m_bodyCenterInitMethod == "BOX_SEED") {
186 } else if(m_bodyCenterInitMethod == "POINT") {
187 m_noEmbeddedBodies = Context::getSolverProperty<MInt>("noEmbeddedBodies", m_solverId, AT_, &m_noEmbeddedBodies);
188
189 const MInt num_initialBodyCenters = Context::propertyLength("initialBodyCenters", m_solverId);
190 for(MInt i = 0; i < num_initialBodyCenters; i++) {
191 m_initialBodyCenters.emplace_back(Context::getSolverProperty<MFloat>("initialBodyCenters", m_solverId, AT_, i));
192 }
193 }
194 }
195
197 m_maxNoBodies = Context::getSolverProperty<MInt>("maxNoBodies", m_solverId, AT_, &m_maxNoBodies);
198
199 m_forcedMotion = Context::getSolverProperty<MBool>("forcedMotion", m_solverId, AT_, &m_forcedMotion);
200
201 m_bodyType = 1;
202 m_bodyType = Context::getSolverProperty<MInt>("bodyTypeMb", m_solverId, AT_, &m_bodyType);
203
204 const MInt num_initBodyRadius = Context::propertyLength("bodyRadius", m_solverId);
205 for(MInt i = 0; i < num_initBodyRadius; i++) {
206 m_initBodyRadius.emplace_back(Context::getSolverProperty<MFloat>("bodyRadius", m_solverId, AT_, i));
207 }
208
209 const MInt num_initBodyRadii = Context::propertyLength("bodyRadii", m_solverId);
210 for(MInt i = 0; i < num_initBodyRadii; i++) {
211 m_initBodyRadii.emplace_back(Context::getSolverProperty<MFloat>("bodyRadii", m_solverId, AT_, i));
212 }
213
214 m_bodyHeight = 1.0;
215 m_bodyHeight = Context::getSolverProperty<MFloat>("bodyHeight", m_solverId, AT_, &m_bodyHeight);
216
217 m_uRef = 1.0;
218 m_uRef = Context::getSolverProperty<MFloat>("uRef", m_solverId, AT_, &m_uRef);
219
220 m_logBodyData = false;
221 m_logBodyData = Context::getSolverProperty<MBool>("logBodyData", m_solverId, AT_, &m_logBodyData);
222
223 // Array-like properties
224 const MInt num_initBodyDensityRatios = Context::propertyLength("bodyDensityRatio", m_solverId);
225 for(MInt i = 0; i < num_initBodyDensityRatios; i++) {
226 m_initBodyDensityRatios.emplace_back(Context::getSolverProperty<MFloat>("bodyDensityRatio", m_solverId, AT_, i));
227 }
228
229 if(Context::propertyExists("gravity", m_solverId)) {
230 for(MInt n = 0; n < nDim; n++) {
231 gravity[n] = Context::getSolverProperty<MFloat>("gravity", m_solverId, AT_, n);
232 gravity[n] /= POW2(m_uRef);
233 }
234 }
235
236 // TODO labels:DOC,toenhance Change to per-body value
239 Context::getSolverProperty<MFloat>("uniformBodyTemperature", m_solverId, AT_, &m_uniformBodyTemperature);
240
241 // allow translation
242 m_translation = true;
243 m_translation = Context::getSolverProperty<MBool>("translation", m_solverId, AT_, &m_translation);
244
245 // allow rotation
246 m_rotation = true;
247 m_rotation = Context::getSolverProperty<MBool>("integrateRotation", m_solverId, AT_, &m_rotation);
248
249 // allow rotation only around z-axis
250 m_rotXYaxis = true;
251 m_rotXYaxis = Context::getSolverProperty<MBool>("rotXYaxis", m_solverId, AT_, &m_rotXYaxis);
252}
static MInt propertyLength(const MString &name, MInt solverId=m_noSolvers)
Returns the number of elements of a property.
Definition: context.cpp:538
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
Definition: context.cpp:494
MString m_bodyCenterInitMethod
Definition: rigidbodies.h:169
void boxSeedInitialize()
MFloat m_uniformBodyTemperature
Definition: rigidbodies.h:161
MBool m_printKineticEnergy
Definition: rigidbodies.h:316
MFloat m_uRef
Definition: rigidbodies.h:183

◆ refineCell()

template<MInt nDim>
void RigidBodies< nDim >::refineCell ( const  MInt)
inlineoverridevirtual

Reimplemented from Solver.

Definition at line 125 of file rigidbodies.h.

125{};

◆ reinitAfterAdaptation()

template<MInt nDim>
void RigidBodies< nDim >::reinitAfterAdaptation ( )
inlineoverridevirtual

Reinit the solver/solver after adaptation TODO labels:toremove remove once all solvers use the split adaptation

Reimplemented from Solver.

Definition at line 124 of file rigidbodies.h.

124{};

◆ reIntAfterRestart()

template<MInt nDim>
void RigidBodies< nDim >::reIntAfterRestart ( MBool  )
inlineoverridevirtual

Reimplemented from Solver.

Definition at line 97 of file rigidbodies.h.

97{};

◆ removeChilds()

template<MInt nDim>
void RigidBodies< nDim >::removeChilds ( const  MInt)
inlineoverridevirtual

Reimplemented from Solver.

Definition at line 122 of file rigidbodies.h.

122{};

◆ resetForce()

template<MInt nDim>
void RigidBodies< nDim >::resetForce ( )
inline

Definition at line 456 of file rigidbodies.h.

456 {
457 // Reset bodyForces
458 std::fill_n(a_bodyForce(0), noCollectorBodies() * nDim, 0.0);
459 }

◆ resetTorque()

template<MInt nDim>
void RigidBodies< nDim >::resetTorque ( )
inline

Definition at line 461 of file rigidbodies.h.

461 {
462 // Reset bodyTorques
463 std::fill_n(a_bodyTorque(0), noCollectorBodies() * nRot, 0.0);
464 }

◆ resizeGridMap()

template<MInt nDim>
void RigidBodies< nDim >::resizeGridMap ( )
inlinevirtual

Reimplemented from Solver.

Definition at line 116 of file rigidbodies.h.

116 {
117 // Note: resize with current tree size since the number of cells should not change
118 grid().resizeGridMap(grid().tree().size());
119 }

◆ saveBodyRestartFile()

template<MInt nDim>
void RigidBodies< nDim >::saveBodyRestartFile ( const MBool  backup)
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
MBoolbackup True if backup restart file should be written (e.g. for the initial conditions)

Definition at line 3930 of file rigidbodies.cpp.

3930 {
3931 TRACE();
3932
3933 using namespace maia::parallel_io;
3934
3935 const MLong noLocal = m_noLocalBodies;
3936 const MLong noGlobal = noEmbeddedBodies();
3937
3938 // Find order in which the data will be written
3939 // Sorting by containing partition cell ensures consistency between runs with different partitioning
3940 std::vector<MInt> localPartitionCellOfBody(noLocal, -1);
3941 for(MUint i = 0; i < noLocal; i++) {
3942 localPartitionCellOfBody[i] = grid().raw().findContainingPartitionCell(&a_bodyCenter(i, 0), -1, nullptr);
3943 }
3944 std::vector<int> indices(noLocal);
3945 // Init unity index mapping
3946 std::iota(indices.begin(), indices.end(), 0);
3947 // Sort indices based on the local partition cell index
3948 std::sort(indices.begin(), indices.end(),
3949 [&](int a, int b) -> bool { return localPartitionCellOfBody[a] < localPartitionCellOfBody[b]; });
3950
3951 if(domainId() == 0) {
3952 std::cerr << "writing body-restart-data ... (rigid bodies) ";
3953 }
3954
3955 static constexpr MLong DOF_SCALAR = 1;
3956 static constexpr MLong DOF_TRANS = nDim;
3957 static constexpr MLong DOF_ROT = nRot;
3958 static constexpr MLong DOF_QUAT = nDim + 1;
3959
3960 const MLong offset = getDomainOffset();
3961
3962 std::cout << "Domain " << domainId() << " has " << noLocal << " and offset " << offset << std::endl;
3963
3964 std::stringstream fileNameStream;
3965 fileNameStream << outputDir() << "restartBodyData_" << globalTimeStep;
3966 fileNameStream << ParallelIo::fileExt();
3967
3968 const MString fileName = fileNameStream.str();
3969
3970 ParallelIo parallelIo(fileName, PIO_REPLACE, mpiComm());
3971
3972 // Creating file header.
3973 parallelIo.defineScalar(PIO_INT, "noBodies");
3974
3975 // Define scalars
3976 parallelIo.defineArray(PIO_FLOAT, "bodyTemperature", noGlobal * DOF_SCALAR);
3977
3978 // Define vectors
3979 parallelIo.defineArray(PIO_FLOAT, "bodyCenter", noGlobal * DOF_TRANS);
3980 parallelIo.defineArray(PIO_FLOAT, "bodyVelocity", noGlobal * DOF_TRANS);
3981 parallelIo.defineArray(PIO_FLOAT, "bodyAcceleration", noGlobal * DOF_TRANS);
3982
3983 // Define rotational vectors
3984 parallelIo.defineArray(PIO_FLOAT, "angularVelocityBodyT1B2", noGlobal * DOF_ROT);
3985 parallelIo.defineArray(PIO_FLOAT, "angularAccelerationBody", noGlobal * DOF_ROT);
3986
3987 // Define rotational bodyQuaternion
3988 parallelIo.defineArray(PIO_FLOAT, "bodyQuaternionT1B2", noGlobal * DOF_QUAT);
3989 parallelIo.defineArray(PIO_FLOAT, "bodyQuaternionT1", noGlobal * DOF_QUAT);
3990
3991 // Write data
3992 parallelIo.writeScalar(noEmbeddedBodies(), "noBodies");
3993
3994 // Scalar
3995 parallelIo.setOffset(noLocal * DOF_SCALAR, offset * DOF_SCALAR);
3996 {
3997 MFloatScratchSpace bufTemperature(noLocal * DOF_SCALAR, AT_, "writeBuffer");
3998 for(MInt i = 0; i < noLocal; i++) {
3999 bufTemperature[i] = a_bodyTemperature(indices[i]);
4000 }
4001 parallelIo.writeArray(bufTemperature.data(), "bodyTemperature");
4002 }
4003
4004 // Translation
4005 parallelIo.setOffset(noLocal * DOF_TRANS, offset * DOF_TRANS);
4006 {
4007 MFloatScratchSpace writeBuffer(noLocal * DOF_TRANS, AT_, "writeBuffer");
4008 for(MInt i = 0; i < noLocal; i++) {
4009 for(MInt n = 0; n < DOF_TRANS; n++) {
4010 writeBuffer[i * DOF_TRANS + n] = a_bodyCenter(indices[i], n);
4011 }
4012 }
4013 parallelIo.writeArray(writeBuffer.data(), "bodyCenter");
4014 }
4015 {
4016 MFloatScratchSpace writeBuffer(noLocal * DOF_TRANS, AT_, "writeBuffer");
4017 for(MInt i = 0; i < noLocal; i++) {
4018 for(MInt n = 0; n < DOF_TRANS; n++) {
4019 writeBuffer[i * DOF_TRANS + n] = a_bodyVelocity(indices[i], n);
4020 }
4021 }
4022 parallelIo.writeArray(writeBuffer.data(), "bodyVelocity");
4023 }
4024 {
4025 MFloatScratchSpace writeBuffer(noLocal * DOF_TRANS, AT_, "writeBuffer");
4026 for(MInt i = 0; i < noLocal; i++) {
4027 for(MInt n = 0; n < DOF_TRANS; n++) {
4028 writeBuffer[i * DOF_TRANS + n] = a_bodyAcceleration(indices[i], n);
4029 }
4030 }
4031 parallelIo.writeArray(writeBuffer.data(), "bodyAcceleration");
4032 }
4033
4034 // Rotation (vector)
4035 parallelIo.setOffset(noLocal * DOF_ROT, offset * DOF_ROT);
4036 {
4037 MFloatScratchSpace writeBuffer(noLocal * DOF_ROT, AT_, "writeBuffer");
4038 for(MInt i = 0; i < noLocal; i++) {
4039 for(MInt n = 0; n < DOF_ROT; n++) {
4040 writeBuffer[i * DOF_ROT + n] = a_angularVelocityBodyT1B2(indices[i], n);
4041 }
4042 }
4043 parallelIo.writeArray(writeBuffer.data(), "angularVelocityBodyT1B2");
4044 }
4045 {
4046 MFloatScratchSpace writeBuffer(noLocal * DOF_ROT, AT_, "writeBuffer");
4047 for(MInt i = 0; i < noLocal; i++) {
4048 for(MInt n = 0; n < DOF_ROT; n++) {
4049 writeBuffer[i * DOF_ROT + n] = a_angularAccelerationBody(indices[i], n);
4050 }
4051 }
4052 parallelIo.writeArray(writeBuffer.data(), "angularAccelerationBody");
4053 }
4054
4055 // Rotation (quaternions)
4056 parallelIo.setOffset(noLocal * DOF_QUAT, offset * DOF_QUAT);
4057 {
4058 MFloatScratchSpace writeBuffer(noLocal * DOF_QUAT, AT_, "writeBuffer");
4059 for(MInt i = 0; i < noLocal; i++) {
4060 for(MInt n = 0; n < DOF_QUAT; n++) {
4061 writeBuffer[i * DOF_QUAT + n] = a_bodyQuaternionT1B2(indices[i], n);
4062 }
4063 }
4064 parallelIo.writeArray(writeBuffer.data(), "bodyQuaternionT1B2");
4065 }
4066 {
4067 MFloatScratchSpace writeBuffer(noLocal * DOF_QUAT, AT_, "writeBuffer");
4068 for(MInt i = 0; i < noLocal; i++) {
4069 for(MInt n = 0; n < DOF_QUAT; n++) {
4070 writeBuffer[i * DOF_QUAT + n] = a_bodyQuaternionT1(indices[i], n);
4071 }
4072 }
4073 parallelIo.writeArray(writeBuffer.data(), "bodyQuaternionT1");
4074 }
4075
4076 if(domainId() == 0) {
4077 std::cerr << "ok" << std::endl;
4078 }
4079}
MString outputDir() const
Definition: rigidbodies.h:266
MLong getDomainOffset()
for new restartFile format
This class is a ScratchSpace.
Definition: scratch.h:758
void indices(const MInt i, const MInt n, MInt *const ids)
Calculate the 2D/3D indices for a given scalar id for accessing a field of n^nDim points.

◆ saveSolverSolution()

template<MInt nDim>
void RigidBodies< nDim >::saveSolverSolution ( const  MBool,
const  MBool 
)
inline

Definition at line 90 of file rigidbodies.h.

90{};

◆ setCellWeights()

template<MInt nDim>
void RigidBodies< nDim >::setCellWeights ( MFloat )
inlineoverridevirtual

Reimplemented from Solver.

Definition at line 128 of file rigidbodies.h.

128{};

◆ setSensors()

template<MInt nDim>
void RigidBodies< nDim >::setSensors ( std::vector< std::vector< MFloat > > &  ,
std::vector< MFloat > &  ,
std::vector< std::bitset< 64 > > &  ,
std::vector< MInt > &   
)
inlineoverridevirtual

Reimplemented from Solver.

Definition at line 112 of file rigidbodies.h.

113 {};

◆ setTimestep()

template<MInt nDim>
void RigidBodies< nDim >::setTimestep ( const MFloat  timestep)
inline

Definition at line 612 of file rigidbodies.h.

612{ m_timestep = timestep; }

◆ size()

template<MInt nDim>
MInt RigidBodies< nDim >::size ( ) const
inline

Definition at line 407 of file rigidbodies.h.

407{ return noCollectorBodies(); }

◆ solutionStep()

template<MInt nDim>
MBool RigidBodies< nDim >::solutionStep
overridevirtual
Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Returns
True if the predictor-corrector cycle has finished

Reimplemented from Solver.

Definition at line 599 of file rigidbodies.cpp.

599 {
600 if(m_newTimeStep) {
601#ifdef RB_DEBUG
603 << "------------TIMESTEP: " << globalTimeStep
604 << " -----------------------------------------------------------------------------------------------"
605 << std::endl;
606#endif
607
608 RECORD_TIMER_START(m_timers[Timers::SolutionStep]);
609
610 RECORD_TIMER_START(m_timers[Timers::Predict]);
612 RECORD_TIMER_STOP(m_timers[Timers::Predict]);
613
614 RECORD_TIMER_START(m_timers[Timers::Communication]);
616 RECORD_TIMER_STOP(m_timers[Timers::Communication]);
617
618 m_newTimeStep = false;
619
620 RECORD_TIMER_STOP(m_timers[Timers::SolutionStep]);
621
622 return false;
623 } else {
624 RECORD_TIMER_START(m_timers[Timers::SolutionStep]);
625
626 RECORD_TIMER_START(m_timers[Timers::Communication]);
628 RECORD_TIMER_STOP(m_timers[Timers::Communication]);
629
630 RECORD_TIMER_START(m_timers[Timers::Correct]);
632 RECORD_TIMER_STOP(m_timers[Timers::Correct]);
633
634 RECORD_TIMER_START(m_timers[Timers::Communication]);
636 RECORD_TIMER_STOP(m_timers[Timers::Communication]);
637
638 RECORD_TIMER_START(m_timers[Timers::UpdateCommunication]);
640 RECORD_TIMER_STOP(m_timers[Timers::UpdateCommunication]);
641
643 RECORD_TIMER_STOP(m_timers[Timers::SolutionStep]);
644
645 return true;
646 }
647}
void correctBodies()
Correcting the state of all bodies using all available external forces/fluxes.
void exchangeFsiData()
exchange of summed forces and torques
void updateConnections()
void computeBodies()
Calculates the new state for all bodies.
void exchangeKinematicData()
exchange of predictor & corrector step output

◆ swapCells()

template<MInt nDim>
void RigidBodies< nDim >::swapCells ( const  MInt,
const  MInt 
)
inlineoverridevirtual

Reimplemented from Solver.

Definition at line 126 of file rigidbodies.h.

126{};

◆ swapProxy()

template<MInt nDim>
void RigidBodies< nDim >::swapProxy ( const MInt  MInt,
const MInt  MInt 
)
inlinevirtual

Reimplemented from Solver.

Definition at line 127 of file rigidbodies.h.

127{ grid().swapGridIds(cellId0, cellId1); }

◆ time()

template<MInt nDim>
MFloat RigidBodies< nDim >::time ( ) const
inlineoverridevirtual

Implements Solver.

Definition at line 93 of file rigidbodies.h.

93{ return 0.0; };

◆ totalKineticEnergy()

template<MInt nDim>
void RigidBodies< nDim >::totalKineticEnergy

Definition at line 523 of file rigidbodies.cpp.

523 {
524 TRACE();
525
527 std::vector<MFloat> recvBuffer;
528 recvBuffer.resize(noDomains());
529
530 MFloat summedKineticEnergy = 0.0;
531 for(MInt bodyId = 0; bodyId < m_noLocalBodies; bodyId++) {
532 summedKineticEnergy += F1B2 * a_bodyDensityRatio(bodyId) * a_volume(bodyId) * POW2(a_bodyVelocityMag(bodyId));
533 }
534
535 MPI_Gather(&summedKineticEnergy, 1, maia::type_traits<MFloat>::mpiType(), recvBuffer.data(), 1,
536 maia::type_traits<MFloat>::mpiType(), 0, mpiComm(), AT_, "send", "recv");
537
539 if(!domainId()) {
540 totalKineticEnergy = std::accumulate(recvBuffer.begin(), recvBuffer.end(), totalKineticEnergy);
541 std::cout << "Total Kinetic Energy of Bodies is: " << totalKineticEnergy << std::endl;
542 }
543}
MFloat a_bodyVelocityMag(const MInt bodyId)
Definition: rigidbodies.h:600
void totalKineticEnergy()
MInt m_solutionInterval
The number of timesteps before writing the next solution file.
Definition: solver.h:74

◆ transformToBodyFrame() [1/2]

template<MInt nDim>
void RigidBodies< nDim >::transformToBodyFrame ( const MFloat *const  bodyQuaternion,
const MFloat *const  vectorWorld,
MFloat *const  vectorBody 
)
inlineprivate

For reference, see L.J.H. Seelen et al., Improved bodyQuaternion-based integration scheme for rigid body motion

Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
bodyQuaternion[in]bodyQuaternion describing the rotational state of the body frame
vectorWorld[in]Vector defined in the world frame
vectorBody[out]Vector defined in the body frame

Definition at line 3124 of file rigidbodies.cpp.

3126 {
3127 const MFloat uv = std::inner_product(bodyQuaternion, &bodyQuaternion[3], vectorWorld, 0.0);
3128 const MFloat uu = std::inner_product(bodyQuaternion, &bodyQuaternion[3], bodyQuaternion, 0.0);
3129 const MFloat ss = bodyQuaternion[3] * bodyQuaternion[3];
3130 MFloat ucv[nRot]{};
3131 IF_CONSTEXPR(nDim == 3) { maia::math::cross(bodyQuaternion, vectorWorld, &ucv[0]); }
3132 else {
3133 return;
3134 }
3135 for(MInt n = 0; n < nRot; n++) {
3136 vectorBody[n] = 2.0 * uv * bodyQuaternion[n] + (ss - uu) * vectorWorld[n] + 2.0 * bodyQuaternion[3] * ucv[n];
3137 }
3138}

◆ transformToBodyFrame() [2/2]

template<MInt nDim>
void RigidBodies< nDim >::transformToBodyFrame ( const MFloat *const  bodyQuaternion,
MFloat *const  vec 
)
inlineprivate

This version modifies the vector in place.

For reference, see L.J.H. Seelen et al., Improved bodyQuaternion-based integration scheme for rigid body motion

Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
bodyQuaternion[in]bodyQuaternion describing the rotational state of the body frame
vectorBody[in,out]Vector to be transformed from the world to body frame

Definition at line 3154 of file rigidbodies.cpp.

3154 {
3155 const MFloat vectorWorld[3]{vec[0], vec[1], vec[2]};
3156 transformToBodyFrame(bodyQuaternion, vectorWorld, vec);
3157}

◆ transformToWorldFrame()

template<MInt nDim>
void RigidBodies< nDim >::transformToWorldFrame ( const MFloat *const  bodyQuaternion,
const MFloat *const  vectorBody,
MFloat *const  vectorWorld 
)
inlineprivate

For reference, see L.J.H. Seelen et al., Improved bodyQuaternion-based integration scheme for rigid body motion

Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
bodyQuaternion[in]bodyQuaternion describing the rotational state of the body frame
vectorBody[in]Vector defined in the body frame
vectorWorld[out]Vector defined in the world frame

Definition at line 3095 of file rigidbodies.cpp.

3097 {
3098 const MFloat uv = std::inner_product(bodyQuaternion, &bodyQuaternion[3], vectorBody, 0.0);
3099 const MFloat uu = std::inner_product(bodyQuaternion, &bodyQuaternion[3], bodyQuaternion, 0.0);
3100 const MFloat ss = bodyQuaternion[3] * bodyQuaternion[3];
3101 MFloat ucv[nRot]{};
3102 IF_CONSTEXPR(nDim == 3) { maia::math::cross(bodyQuaternion, vectorBody, &ucv[0]); }
3103 else {
3104 return;
3105 }
3106 for(MInt n = 0; n < nRot; n++) {
3107 vectorWorld[n] = 2.0 * uv * bodyQuaternion[n] + (ss - uu) * vectorBody[n] + 2.0 * bodyQuaternion[3] * -(ucv[n]);
3108 }
3109}

◆ updateBodyDomainConnections()

template<MInt nDim>
void RigidBodies< nDim >::updateBodyDomainConnections ( MBool  initCall)

updates all local lists + mappings

Author
Oliver Groll olive.nosp@m.r.gr.nosp@m.oll@r.nosp@m.wth-.nosp@m.aache.nosp@m.n.de Johannes Grafen johan.nosp@m.nes..nosp@m.grafe.nosp@m.n@rw.nosp@m.th-aa.nosp@m.chen.nosp@m..des

Definition at line 1856 of file rigidbodies.cpp.

1856 {
1857 TRACE();
1858
1859#ifdef RB_DEBUG
1860 m_debugFileStream << "entering updateBodyDomainConnections on domain " << domainId() << std::endl;
1862#endif
1863
1864 for(MInt i = 0; i < noNeighborDomains(); i++) {
1865 /* 1) if local body are intersecting with Halo Partition Cells
1866 ** copy local body -> edge body
1867 */
1868 MInt globDomain = neighborDomain(i);
1869 for(MInt bodyId = 0; bodyId < noConnectingBodies(); bodyId++) {
1870 MBool alreadyInside = std::binary_search(m_remoteDomainLocalBodies[globDomain].begin(),
1871 m_remoteDomainLocalBodies[globDomain].end(), bodyId);
1872
1873 MBool alreadySelfMapped = m_periodicBC && hasAssociatedDummyBody(bodyId);
1874
1875#ifdef RB_DEBUG
1876 m_debugFileStream << "D" << globDomain << " lBody " << bodyId << " already in mapping " << alreadyInside
1877 << " selfmapped " << alreadySelfMapped << std::endl;
1878 for(auto&& b : m_remoteDomainLocalBodies[globDomain]) {
1879 m_debugFileStream << "[" << globDomain << "," << b << "]" << std::endl;
1880 }
1881 m_debugFileStream << std::endl;
1882#endif
1883 if(alreadyInside || alreadySelfMapped) {
1884 continue;
1885 }
1886
1887 MInt intersectingCellId =
1888 grid().raw().intersectingWithHaloCells(&a_bodyCenter(bodyId, 0), m_infoDiameter / 2.0, i, true);
1889 if(intersectingCellId != -1) {
1890 if(domainId() == globDomain && m_periodicBC
1891 && grid().raw().a_hasProperty(intersectingCellId, Cell::IsPeriodic)) {
1892 // Hande Self-Mapping Case: A domain does not have to send something to itself, so the dummyBody does not
1893 // appear in the domain - body mappings, but a dummy has still to be added to collector, as the body has now
1894 // to different positions of the bodycenter, in the periodic case
1895 createDummyBody(bodyId);
1896 } else if(isLocalBody(bodyId)) {
1897 // Regular handling of edgeBodies, that have a remoteDomain
1898 std::vector<MInt>* bodyIds = &(m_remoteDomainLocalBodies[globDomain]);
1899 if(!std::binary_search(bodyIds->begin(), bodyIds->end(), bodyId)) {
1900 // Insert at the right position to keep this mapping sorted by the local body id
1901 bodyIds->insert(std::upper_bound(bodyIds->begin(), bodyIds->end(), bodyId), bodyId);
1902 }
1903 }
1904 }
1905 }
1906
1907
1908 /* 2) if edge body is no longer intersecting halo partition cells
1909 ** remove edge body -> []
1910 */
1911 std::vector<MInt> removeList;
1912 for(const MInt& bodyId : m_remoteDomainLocalBodies[globDomain]) {
1913 // checking only partition halo cells
1914 MInt intersectingCellId =
1915 grid().raw().intersectingWithHaloCells(&a_bodyCenter(bodyId, 0), m_infoDiameter / 2.0, i, true);
1916 if(intersectingCellId == -1) {
1917 // body is no longer intersecting haloPartitionCell (body has left domain ->
1918 // body that was previously marked as transferBody and now needs to be removed from edgeBodies of homeDomain)
1919 removeList.push_back(bodyId);
1920 }
1921 }
1922
1923#ifdef RB_DEBUG
1924 if(!removeList.empty()) {
1925 MString removeListS = "[";
1926 for(const MInt& body : removeList) {
1927 removeListS += std::to_string(body) + ", ";
1928 }
1929 removeListS += "] ";
1930 m_debugFileStream << "RemoveList for domain " << domainId() << " " << removeListS
1931 << " neighborDomain: " << neighborDomain(i) << std::endl;
1932 }
1933#endif
1934
1935 for(const auto& body : removeList) {
1936 // body is not remote on other domain, remove it from mapping and edgeBodies
1937 std::vector<MInt>* bodies = &m_remoteDomainLocalBodies[neighborDomain(i)];
1938 bodies->erase(std::remove(bodies->begin(), bodies->end(), body), bodies->end());
1939 }
1940 }
1941
1942 /* 3) if edge body intersects a periodic halo partition cell
1943 ** calculate periodic shift
1944 */
1945 if(m_periodicBC) {
1946 m_periodicShift.clear();
1947 // determine periodicShift for bodies that are remote on Neighbors
1948 for(MInt i = 0; i < noNeighborDomains(); i++) {
1949 MInt globDomain = neighborDomain(i);
1950
1951 if(globDomain == domainId()) continue;
1952
1953 for(const auto& bodyId : m_remoteDomainLocalBodies[globDomain]) {
1954 std::array<MFloat, nDim> center{};
1955 for(MInt n = 0; n < nDim; n++) {
1956 center[n] = a_bodyCenter(bodyId, n);
1957 }
1958 const MInt intersectingCellId =
1959 grid().raw().intersectingWithHaloCells(center.data(), m_infoDiameter / 2.0, i, true);
1960 std::array<MFloat, nDim> tmpShift{};
1961 for(MInt n = 0; n < nDim; n++) {
1962 tmpShift[n] = calculatePeriodicShift(intersectingCellId, n);
1963 }
1964 const MInt globalDomain = neighborDomain(i);
1965 m_periodicShift[globalDomain][bodyId] = tmpShift;
1966 }
1967 }
1968
1969 // Now handle Self-Mapped Bodies
1970 for(const auto& [localBodyId, dummyBodyId] : m_associatedDummyBodies) {
1971 std::array<MFloat, nDim> center{};
1972 for(MInt n = 0; n < nDim; n++) {
1973 center[n] = a_bodyCenter(localBodyId, n);
1974 }
1975 const MInt intersectingCellId =
1976 grid().raw().intersectingWithHaloCells(center.data(), m_infoDiameter / 2.0, 0, true);
1977 std::array<MFloat, nDim> tmpShift{};
1978 for(MInt n = 0; n < nDim; n++) {
1979 tmpShift[n] = calculatePeriodicShift(intersectingCellId, n);
1980 }
1981 m_periodicShift[domainId()][localBodyId] = tmpShift;
1982 }
1983
1984#ifdef RB_DEBUG
1985 MString periodicShiftS{};
1986 for(const auto& [domain, bodies] : m_periodicShift) {
1987 periodicShiftS += "on domain " + std::to_string(domain) + " periodic Shifts are: \n";
1988 for(const auto& [bodyId, shift] : bodies) {
1989 periodicShiftS += " bodyId: " + std::to_string(bodyId) + " [";
1990 for(MInt n = 0; n < nDim; n++) {
1991 periodicShiftS += std::to_string(shift[n]) + " ";
1992 }
1993 periodicShiftS += "] \n";
1994 }
1995 }
1996 m_debugFileStream << periodicShiftS;
1997#endif
1998 }
1999}
MBool isLocalBody(MInt bodyId)
Definition: rigidbodies.h:417

◆ updateConnections()

template<MInt nDim>
void RigidBodies< nDim >::updateConnections

Definition at line 909 of file rigidbodies.cpp.

909 {
910 TRACE();
917// exchangeNeighborConnectionInfo();
918#ifdef RB_DEBUG
920#endif
922}
void checkDummyBodiesForSwap()
void findTransferBodies()
creates list with all edge bodies that are no longer contained within local domain
void exchangeTransferBodies()
exchanges transfer bodies

◆ updateInfoDiameter()

template<MInt nDim>
void RigidBodies< nDim >::updateInfoDiameter ( const MBool  initCall = false)

Definition at line 1522 of file rigidbodies.cpp.

1522 {
1523 TRACE();
1524 std::vector<MInt> l_Bodies;
1525 MFloat maxBodyExtension = F0;
1526
1527 if(initCall) {
1528 for(MInt i = 0; i < m_noLocalBodies; i++) {
1529 l_Bodies.push_back(i);
1530 }
1531 } else {
1532 for(MInt bodyId = 0; bodyId < noCollectorBodies(); bodyId++) {
1533 l_Bodies.push_back(bodyId);
1534 }
1535 }
1536
1537 if(m_initBodyRadii.empty()) {
1538 for(const MInt& bodyId : l_Bodies) {
1539 maxBodyExtension = std::max(maxBodyExtension, 2 * a_bodyRadius(bodyId));
1540 }
1541 } else {
1542 for(const MInt& bodyId : l_Bodies) {
1543 for(MInt n = 0; n < nDim; n++) {
1544 maxBodyExtension = std::max(maxBodyExtension, 2 * a_bodyRadii(bodyId, n));
1545 }
1546 }
1547 }
1548 // Body extension + buffer
1549 constexpr const MInt noCellsClearance = 4.0;
1550 m_infoDiameter = maxBodyExtension + noCellsClearance * c_cellLengthAtMaxLevel();
1551}

◆ updateMaxLevel()

template<MInt nDim>
void RigidBodies< nDim >::updateMaxLevel ( MInt  newMaxLevel)
inline

Definition at line 341 of file rigidbodies.h.

341{ m_currMaxLevel = newMaxLevel; }

◆ writeRestartFile()

template<MInt nDim>
void RigidBodies< nDim >::writeRestartFile ( const MBool  writeRestart,
const MBool  writeBackup,
const  MString,
MInt  
)
overridevirtual

Checks if the restart file should be saved in the current time step

Author
Julian Vorspohl j.vor.nosp@m.spoh.nosp@m.l@aia.nosp@m..rwt.nosp@m.h-aac.nosp@m.hen..nosp@m.de
Parameters
[in]writeRestartTrue if a restart file should be written
[in]writeBackupTrue if a backup restart file should be written (e.g. for the initial conditions)
[in]gridFileNameName of the corresponding grid file name
[in]recalcIdsUse id ordering give in grid file

Reimplemented from Solver.

Definition at line 3914 of file rigidbodies.cpp.

3915 {
3916 TRACE();
3917 if(writeRestart || globalTimeStep % restartInterval() == 0) {
3918 saveBodyRestartFile(writeBackup);
3919 }
3920}
void saveBodyRestartFile(const MBool backup)
Write restart file for the RigidBody solver.
MInt restartInterval() const
Return the restart interval of this solver.
Definition: solver.h:419

Member Data Documentation

◆ gravity

template<MInt nDim>
std::array<MFloat, nDim> RigidBodies< nDim >::gravity {}
private

Definition at line 177 of file rigidbodies.h.

◆ m_anglog

template<MInt nDim>
std::ofstream RigidBodies< nDim >::m_anglog

Definition at line 321 of file rigidbodies.h.

◆ m_associatedDummyBodies

template<MInt nDim>
std::map<MInt, MInt> RigidBodies< nDim >::m_associatedDummyBodies
private

Definition at line 290 of file rigidbodies.h.

◆ m_bodies

template<MInt nDim>
maia::rb::collector::RigidBodyCollector<nDim> RigidBodies< nDim >::m_bodies
private

Definition at line 152 of file rigidbodies.h.

◆ m_bodyCenterInitMethod

template<MInt nDim>
MString RigidBodies< nDim >::m_bodyCenterInitMethod {}
private

Definition at line 169 of file rigidbodies.h.

◆ m_bodyHeatCapacity

template<MInt nDim>
const MFloat RigidBodies< nDim >::m_bodyHeatCapacity = 1.0
private

Definition at line 160 of file rigidbodies.h.

◆ m_bodyHeight

template<MInt nDim>
MFloat RigidBodies< nDim >::m_bodyHeight {}
private

Definition at line 157 of file rigidbodies.h.

◆ m_bodyType

template<MInt nDim>
MInt RigidBodies< nDim >::m_bodyType = 1
private

Definition at line 170 of file rigidbodies.h.

◆ m_bodyWasDeleted

template<MInt nDim>
MBool RigidBodies< nDim >::m_bodyWasDeleted = false

Definition at line 318 of file rigidbodies.h.

◆ m_bResFile

template<MInt nDim>
maia::rb::collector::RigidBodyCollector<nDim> RigidBodies< nDim >::m_bResFile
private

Definition at line 155 of file rigidbodies.h.

◆ m_currMaxLevel

template<MInt nDim>
MInt RigidBodies< nDim >::m_currMaxLevel {}

Definition at line 315 of file rigidbodies.h.

◆ m_debugFileStream

template<MInt nDim>
std::ofstream RigidBodies< nDim >::m_debugFileStream

Definition at line 322 of file rigidbodies.h.

◆ m_distFac

template<MInt nDim>
std::array<MFloat, 2> RigidBodies< nDim >::m_distFac {}

Definition at line 312 of file rigidbodies.h.

◆ m_forcedMotion

template<MInt nDim>
MBool RigidBodies< nDim >::m_forcedMotion = false
private

Definition at line 172 of file rigidbodies.h.

◆ m_geometry

template<MInt nDim>
Geom* RigidBodies< nDim >::m_geometry

Definition at line 79 of file rigidbodies.h.

◆ m_globalBodyIds

template<MInt nDim>
std::vector<MInt> RigidBodies< nDim >::m_globalBodyIds
private

Definition at line 298 of file rigidbodies.h.

◆ m_globDomainLength

template<MInt nDim>
std::array<MFloat, nDim> RigidBodies< nDim >::m_globDomainLength
private

Definition at line 301 of file rigidbodies.h.

◆ m_homeDomainRemoteBodies

template<MInt nDim>
std::map<MInt, std::vector<MInt> > RigidBodies< nDim >::m_homeDomainRemoteBodies
private

Definition at line 294 of file rigidbodies.h.

◆ m_indirectHomeDomains

template<MInt nDim>
std::vector<MInt> RigidBodies< nDim >::m_indirectHomeDomains
private

Definition at line 286 of file rigidbodies.h.

◆ m_infoDiameter

template<MInt nDim>
MFloat RigidBodies< nDim >::m_infoDiameter {}

Definition at line 313 of file rigidbodies.h.

◆ m_initBodyDensityRatios

template<MInt nDim>
std::vector<MFloat> RigidBodies< nDim >::m_initBodyDensityRatios
private

Definition at line 190 of file rigidbodies.h.

◆ m_initBodyRadii

template<MInt nDim>
std::vector<MFloat> RigidBodies< nDim >::m_initBodyRadii
private

Definition at line 194 of file rigidbodies.h.

◆ m_initBodyRadius

template<MInt nDim>
std::vector<MFloat> RigidBodies< nDim >::m_initBodyRadius
private

Definition at line 192 of file rigidbodies.h.

◆ m_initialBodyCenters

template<MInt nDim>
std::vector<MFloat> RigidBodies< nDim >::m_initialBodyCenters
private

Definition at line 189 of file rigidbodies.h.

◆ m_intervalBodyLog

template<MInt nDim>
MInt RigidBodies< nDim >::m_intervalBodyLog = 1

Definition at line 319 of file rigidbodies.h.

◆ m_log

template<MInt nDim>
std::ofstream RigidBodies< nDim >::m_log

Definition at line 320 of file rigidbodies.h.

◆ m_logAngVars

template<MInt nDim>
std::vector<MString> RigidBodies< nDim >::m_logAngVars
private

Definition at line 180 of file rigidbodies.h.

◆ m_logBodyData

template<MInt nDim>
MBool RigidBodies< nDim >::m_logBodyData = false

Definition at line 317 of file rigidbodies.h.

◆ m_logVars

template<MInt nDim>
std::vector<MString> RigidBodies< nDim >::m_logVars
private

Definition at line 179 of file rigidbodies.h.

◆ m_maxNoBodies

template<MInt nDim>
MInt RigidBodies< nDim >::m_maxNoBodies {}
private

Definition at line 167 of file rigidbodies.h.

◆ m_maxSensorLevel

template<MInt nDim>
MInt RigidBodies< nDim >::m_maxSensorLevel {}

Definition at line 314 of file rigidbodies.h.

◆ m_newTimeStep

template<MInt nDim>
MBool RigidBodies< nDim >::m_newTimeStep = true
private

Definition at line 148 of file rigidbodies.h.

◆ m_noDummyBodies

template<MInt nDim>
MInt RigidBodies< nDim >::m_noDummyBodies = 0
private

Definition at line 283 of file rigidbodies.h.

◆ m_noEmbeddedBodies

template<MInt nDim>
MInt RigidBodies< nDim >::m_noEmbeddedBodies = 1
private

Definition at line 168 of file rigidbodies.h.

◆ m_noLocalBodies

template<MInt nDim>
MInt RigidBodies< nDim >::m_noLocalBodies = 0
private

Definition at line 277 of file rigidbodies.h.

◆ m_noRemoteBodies

template<MInt nDim>
MInt RigidBodies< nDim >::m_noRemoteBodies = 0
private

Definition at line 280 of file rigidbodies.h.

◆ m_outputDir

template<MInt nDim>
MString RigidBodies< nDim >::m_outputDir
private

Definition at line 164 of file rigidbodies.h.

◆ m_periodicBC

template<MInt nDim>
MBool RigidBodies< nDim >::m_periodicBC = false
private

Definition at line 300 of file rigidbodies.h.

◆ m_periodicShift

template<MInt nDim>
std::map<MInt, std::map<MInt, std::array<MFloat, nDim> > > RigidBodies< nDim >::m_periodicShift
private

Definition at line 296 of file rigidbodies.h.

◆ m_printKineticEnergy

template<MInt nDim>
MBool RigidBodies< nDim >::m_printKineticEnergy = false

Definition at line 316 of file rigidbodies.h.

◆ m_remoteDomainLocalBodies

template<MInt nDim>
std::map<MInt, std::vector<MInt> > RigidBodies< nDim >::m_remoteDomainLocalBodies
private

Definition at line 292 of file rigidbodies.h.

◆ m_restart

template<MInt nDim>
MBool RigidBodies< nDim >::m_restart = false
private

Definition at line 176 of file rigidbodies.h.

◆ m_restartDir

template<MInt nDim>
MString RigidBodies< nDim >::m_restartDir
private

Definition at line 178 of file rigidbodies.h.

◆ m_restartTimeStep

template<MInt nDim>
MInt RigidBodies< nDim >::m_restartTimeStep = 0
private

Definition at line 171 of file rigidbodies.h.

◆ m_rotation

template<MInt nDim>
MBool RigidBodies< nDim >::m_rotation = true
private

Definition at line 174 of file rigidbodies.h.

◆ m_rotXYaxis

template<MInt nDim>
MBool RigidBodies< nDim >::m_rotXYaxis = true
private

Definition at line 175 of file rigidbodies.h.

◆ m_static_computeBodyProperties_amplitude

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_amplitude = nullptr
private

Definition at line 198 of file rigidbodies.h.

◆ m_static_computeBodyProperties_bodyToFunction

template<MInt nDim>
MInt* RigidBodies< nDim >::m_static_computeBodyProperties_bodyToFunction = nullptr
private

Definition at line 210 of file rigidbodies.h.

◆ m_static_computeBodyProperties_circleStartAngle

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_circleStartAngle = nullptr
private

Definition at line 208 of file rigidbodies.h.

◆ m_static_computeBodyProperties_first

template<MInt nDim>
MBool RigidBodies< nDim >::m_static_computeBodyProperties_first = true
private

Definition at line 197 of file rigidbodies.h.

◆ m_static_computeBodyProperties_freqFactor

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_freqFactor = nullptr
private

Definition at line 199 of file rigidbodies.h.

◆ m_static_computeBodyProperties_initialBodyCenter

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_initialBodyCenter = nullptr
private

Definition at line 200 of file rigidbodies.h.

◆ m_static_computeBodyProperties_liftEndAngle1

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_liftEndAngle1 = nullptr
private

Definition at line 205 of file rigidbodies.h.

◆ m_static_computeBodyProperties_liftEndAngle2

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_liftEndAngle2 = nullptr
private

Definition at line 207 of file rigidbodies.h.

◆ m_static_computeBodyProperties_liftStartAngle1

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_liftStartAngle1 = nullptr
private

Definition at line 204 of file rigidbodies.h.

◆ m_static_computeBodyProperties_liftStartAngle2

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_liftStartAngle2 = nullptr
private

Definition at line 206 of file rigidbodies.h.

◆ m_static_computeBodyProperties_mu

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_mu = nullptr
private

Definition at line 202 of file rigidbodies.h.

◆ m_static_computeBodyProperties_mu2

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_mu2 = nullptr
private

Definition at line 203 of file rigidbodies.h.

◆ m_static_computeBodyProperties_normal

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_normal = nullptr
private

Definition at line 209 of file rigidbodies.h.

◆ m_static_computeBodyProperties_omega

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_omega = nullptr
private

Definition at line 211 of file rigidbodies.h.

◆ m_static_computeBodyProperties_rotAngle

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_rotAngle = nullptr
private

Definition at line 212 of file rigidbodies.h.

◆ m_static_computeBodyProperties_Strouhal

template<MInt nDim>
MFloat* RigidBodies< nDim >::m_static_computeBodyProperties_Strouhal = nullptr
private

Definition at line 201 of file rigidbodies.h.

◆ m_timers

template<MInt nDim>
std::array<MInt, Timers::_count> RigidBodies< nDim >::m_timers
private

Definition at line 256 of file rigidbodies.h.

◆ m_timerType

template<MInt nDim>
MString RigidBodies< nDim >::m_timerType
private

Definition at line 257 of file rigidbodies.h.

◆ m_timestep

template<MInt nDim>
MFloat RigidBodies< nDim >::m_timestep = 0
private

Definition at line 186 of file rigidbodies.h.

◆ m_timesteps

template<MInt nDim>
MInt RigidBodies< nDim >::m_timesteps = 0
private

Definition at line 187 of file rigidbodies.h.

◆ m_transferBodies

template<MInt nDim>
std::vector<std::vector<MInt> > RigidBodies< nDim >::m_transferBodies
private

Definition at line 288 of file rigidbodies.h.

◆ m_translation

template<MInt nDim>
MBool RigidBodies< nDim >::m_translation = true
private

Definition at line 173 of file rigidbodies.h.

◆ m_uniformBodyTemperature

template<MInt nDim>
MFloat RigidBodies< nDim >::m_uniformBodyTemperature {}
private

Definition at line 161 of file rigidbodies.h.

◆ m_uRef

template<MInt nDim>
MFloat RigidBodies< nDim >::m_uRef {}
private

Definition at line 183 of file rigidbodies.h.

◆ nQuat

template<MInt nDim>
constexpr MInt RigidBodies< nDim >::nQuat = (nDim == 3) ? 4 : 0
staticconstexprprivate

Definition at line 132 of file rigidbodies.h.

◆ nRot

template<MInt nDim>
constexpr MInt RigidBodies< nDim >::nRot = (nDim == 3) ? 3 : 1
staticconstexprprivate

Definition at line 131 of file rigidbodies.h.


The documentation for this class was generated from the following files: