/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2020 Matthieu Schaller (schaller@strw.leidenuniv.nl)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
******************************************************************************/
#ifndef SWIFT_MULTIPOLE_STRUCT_H
#define SWIFT_MULTIPOLE_STRUCT_H
/* Config parameters. */
#include
/* Local includes */
#include "timeline.h"
/**
* @brief Alignment of the structure for allocation
*/
#define multipole_align 128
/**
* @brief Field tensor components at the location of the multipole.
*/
struct grav_tensor {
/* 0th order terms */
float F_000;
#if SELF_GRAVITY_MULTIPOLE_ORDER > 0
/* 1st order terms */
float F_100, F_010, F_001;
#endif
#if SELF_GRAVITY_MULTIPOLE_ORDER > 1
/* 2nd order terms */
float F_200, F_020, F_002;
float F_110, F_101, F_011;
#endif
#if SELF_GRAVITY_MULTIPOLE_ORDER > 2
/* 3rd order terms */
float F_300, F_030, F_003;
float F_210, F_201;
float F_120, F_021;
float F_102, F_012;
float F_111;
#endif
#if SELF_GRAVITY_MULTIPOLE_ORDER > 3
/* 4th order terms */
float F_400, F_040, F_004;
float F_310, F_301;
float F_130, F_031;
float F_103, F_013;
float F_220, F_202, F_022;
float F_211, F_121, F_112;
#endif
#if SELF_GRAVITY_MULTIPOLE_ORDER > 4
/* 5th order terms */
float F_005, F_014, F_023;
float F_032, F_041, F_050;
float F_104, F_113, F_122;
float F_131, F_140, F_203;
float F_212, F_221, F_230;
float F_302, F_311, F_320;
float F_401, F_410, F_500;
#endif
#if SELF_GRAVITY_MULTIPOLE_ORDER > 5
#error "Missing implementation for order >5"
#endif
#ifdef SWIFT_GRAVITY_FORCE_CHECKS
/* Number of gparts interacted through the tree. */
long long num_interacted_tree;
/* Number of gparts interacted through the FFT mesh */
long long num_interacted_pm;
#endif
#ifdef SWIFT_DEBUG_CHECKS
/* Total number of gpart this field tensor interacted with */
long long num_interacted;
/* Last time this tensor was zeroed */
integertime_t ti_init;
#endif
/* Has this tensor received any contribution? */
char interacted;
};
/**
* @brief The properties of the gravity multipole.
*/
struct multipole {
/*! Bulk velocity */
float vel[3];
/*! Maximal velocity along each axis of all #gpart */
float max_delta_vel[3];
/*! Minimal velocity along each axis of all #gpart */
float min_delta_vel[3];
/*! Maximal co-moving softening of all the #gpart in the mulipole */
float max_softening;
/*! Minimal acceleration norm of all the #gpart in the mulipole */
float min_old_a_grav_norm;
/*! Mulipole power for the different orders */
float power[SELF_GRAVITY_MULTIPOLE_ORDER + 1];
/* 0th order term */
float M_000;
#if SELF_GRAVITY_MULTIPOLE_ORDER > 0
/* 1st order terms (all 0 since we expand around CoM) */
// float M_100, M_010, M_001;
#endif
#if SELF_GRAVITY_MULTIPOLE_ORDER > 1
/* 2nd order terms */
float M_200, M_020, M_002;
float M_110, M_101, M_011;
#endif
#if SELF_GRAVITY_MULTIPOLE_ORDER > 2
/* 3rd order terms */
float M_300, M_030, M_003;
float M_210, M_201;
float M_120, M_021;
float M_102, M_012;
float M_111;
#endif
#if SELF_GRAVITY_MULTIPOLE_ORDER > 3
/* 4th order terms */
float M_400, M_040, M_004;
float M_310, M_301;
float M_130, M_031;
float M_103, M_013;
float M_220, M_202, M_022;
float M_211, M_121, M_112;
#endif
#if SELF_GRAVITY_MULTIPOLE_ORDER > 4
/* 5th order terms */
float M_005, M_014, M_023;
float M_032, M_041, M_050;
float M_104, M_113, M_122;
float M_131, M_140, M_203;
float M_212, M_221, M_230;
float M_302, M_311, M_320;
float M_401, M_410, M_500;
#endif
#if SELF_GRAVITY_MULTIPOLE_ORDER > 5
#error "Missing implementation for order >5"
#endif
#if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_GRAVITY_FORCE_CHECKS)
/* Total number of gpart in this multipole */
long long num_gpart;
#endif
};
/**
* @brief The multipole expansion of a mass distribution.
*/
struct gravity_tensors {
union {
/*! Linking pointer for "memory management". */
struct gravity_tensors *next;
/*! The actual content */
struct {
/*! Field tensor for the potential */
struct grav_tensor pot;
/*! Multipole mass */
struct multipole m_pole;
/*! Centre of mass of the matter dsitribution */
double CoM[3];
/*! Centre of mass of the matter dsitribution at the last rebuild */
double CoM_rebuild[3];
/*! Upper limit of the CoM<->gpart distance */
double r_max;
/*! Upper limit of the CoM<->gpart distance at the last rebuild */
double r_max_rebuild;
};
};
} SWIFT_STRUCT_ALIGN;
/**
* @brief Values returned by the M2P kernel.
*/
struct reduced_grav_tensor {
/* 0th order terms */
float F_000;
/* 1st order terms */
float F_100;
float F_010;
float F_001;
};
#ifdef WITH_MPI
/* MPI datatypes for transfers */
extern MPI_Datatype multipole_mpi_type;
extern MPI_Op multipole_mpi_reduce_op;
void multipole_create_mpi_types(void);
void multipole_free_mpi_types(void);
#endif
#endif /* SWIFT_MULTIPOLE_STRUCT_H */