InternalFields.hh 7.49 KB
/*
 * File:   InternalFields_.hh
 * Author: Furkan - AKKA I&S
 *
 * Created on July 11, 2022, 4:14 PM
 */
#ifndef INTERNALFIELDS_HH
#define INTERNALFIELDS_HH

#include "libinternalfield.h"
#include "libcon2020/libcon2020.h"

#include "Parameter.hh"
#include "ParamData.hh"
#include "DataTypeMath.hh"
#include "Operation.hh"
#include <vector>

using namespace std;

namespace AMDA
{
    namespace Parameters
    {
        template <typename DataType, class TOutputParamData>
        class InternalFields : public Operation
        {
        public:
            InternalFields(Process &pProcess, ParamDataSpec<vector<DataType>> &paramInput, const std::string &modelname, string outputCoord, const unsigned int addCon2020)
                : Operation(pProcess), _paramInput(paramInput),
                  _paramOutput(new TOutputParamData()), _modelname(modelname), _outputCoord(outputCoord), _addCon2020(addCon2020)
            {
                _paramDataOutput = _paramOutput;
            }

            virtual ~InternalFields()
            {
            }
            void write(ParamDataIndexInfo &pParamDataIndexInfo)
            {
                for (unsigned int _index = pParamDataIndexInfo._startIndex;
                     _index < pParamDataIndexInfo._startIndex + pParamDataIndexInfo._nbDataToProcess;
                     ++_index)
                {
                    vector<DataType> in = _paramInput.getDataList()[_index];
                    if (in[0] == 0)
                        in[0] = 1e-31;

                    double crtTime = _paramInput.getTime(_index);
                    vector<DataType> outputBxyz, outputBrtp;
                    outputBxyz.resize(3);
                    outputBrtp.resize(3);
                    DataType outputBm;
                    /* Creation of the output vectors */
                    if (_outputCoord == "cart")
                    {
                        GetJupiterField(in, true, outputBxyz);
                    }
                    else if (_outputCoord == "pol" || _outputCoord == "mag")
                    {
                        GetJupiterField(in, false, outputBrtp);
                    }

                    outputBm = sqrt(outputBrtp[0] * outputBrtp[0] + outputBrtp[1] * outputBrtp[1] + outputBrtp[2] * outputBrtp[2]);

                    _paramOutput->pushTime(crtTime);
                    pushResult(outputBrtp, outputBm, outputBxyz);
                }
            }
            int GetJupiterField(vector<DataType> &inputCartCoord, bool SetCartOut, vector<DataType> &outputB)
            {
                /* set the model */
                _internalModel.SetModel(_modelname.c_str());

                /* set intput and output coordinates */
                _internalModel.SetCartIn(true);
                _internalModel.SetCartOut(SetCartOut);

                /* output field */
                double Br, Bt, Bp;
                _internalModel.Field(inputCartCoord[0], inputCartCoord[1], inputCartCoord[2], &Br, &Bt, &Bp);

                /* Con2020 calculation to add if necessary */
                double Be0, Be1, Be2;
                if (_addCon2020 > 0)
                {
                    _con2020.SetCartIn(true);
                    _con2020.SetCartOut(SetCartOut);
                    switch (_addCon2020)
                    {
                    case 1:
                        _con2020.SetEqType("analytic");  // Fast
                        break;
                    case 2:
                        _con2020.SetEqType("integral");  // Slow
                        break;
                    case 3:
                        _con2020.SetEqType("hybrid");    // In between
                        break;

                    default:
                        _con2020.SetEqType("analytic");
                        break;
                    }
                    _con2020.Field(inputCartCoord[0], inputCartCoord[1], inputCartCoord[2], &Be0, &Be1, &Be2);
                }
                else
                {
                    Be0 = 0.0;
                    Be1 = 0.0;
                    Be2 = 0.0;
                }

                outputB[0] = Br + Be0;
                outputB[1] = Bt + Be1;
                outputB[2] = Bp + Be2;

                return true;
            }

        protected:
            virtual void
            pushResult(vector<DataType> field_pol, DataType magnitude_, vector<DataType> field_cart) = 0;
            ParamDataSpec<std::vector<DataType>> &_paramInput;
            TOutputParamData *_paramOutput;
            Con2020 _con2020;
            InternalModel _internalModel;
            std::string _modelname;
            string _outputCoord;
            unsigned int _addCon2020;
        };

        template <typename DataType>
        class InternalFieldCart : public InternalFields<DataType, ParamDataSpec<vector<DataType>>>
        {
        public:
            /**
             * @brief Constructor.
             * @details Create the ParamData type of the input ParamData.
             */
            InternalFieldCart(Process &pProcess, ParamDataSpec<vector<DataType>> &paramInput, const std::string &modelname, const unsigned int addCon2020) : InternalFields<DataType, ParamDataSpec<vector<DataType>>>(pProcess, paramInput, modelname, "cart", addCon2020)
            {
            }

            virtual ~InternalFieldCart()
            {
            }

        protected:
            virtual void pushResult(vector<DataType> /*_fieldPol*/, DataType /*magnitude_*/, vector<DataType> _fieldCart)
            {
                InternalFields<DataType, ParamDataSpec<vector<DataType>>>::_paramOutput->getDataList().push_back(_fieldCart);
            }
        };

        template <typename DataType>
        class InternalFieldMag : public InternalFields<DataType, ParamDataSpec<DataType>>
        {
        public:
            /**
             * @brief Constructor.
             * @details Create the ParamData type of the input ParamData.
             */
            InternalFieldMag(Process &pProcess, ParamDataSpec<vector<DataType>> &paramInput, const std::string &modelname, const unsigned int addCon2020) : InternalFields<DataType, ParamDataSpec<DataType>>(pProcess, paramInput, modelname, "mag", addCon2020)
            {
            }

            virtual ~InternalFieldMag()
            {
            }

        protected:
            virtual void pushResult(vector<DataType> /*_fieldPol*/, DataType _magnetude, vector<DataType> /*_fieldCart*/)
            {
                InternalFields<DataType, ParamDataSpec<DataType>>::_paramOutput->getDataList().push_back(_magnetude);
            }
        };

        template <typename DataType>
        class InternalFieldPol : public InternalFields<DataType, ParamDataSpec<vector<DataType>>>
        {
        public:
            /**
             * @brief Constructor.
             * @details Create the ParamData type of the input ParamData.
             */
            InternalFieldPol(Process &pProcess, ParamDataSpec<vector<DataType>> &paramInput, const std::string &modelname, const unsigned int addCon2020) : InternalFields<DataType, ParamDataSpec<vector<DataType>>>(pProcess, paramInput, modelname, "pol", addCon2020)
            {
            }

            virtual ~InternalFieldPol()
            {
            }

        protected:
            virtual void pushResult(vector<DataType> _fieldPol, DataType /* _magnetude*/, vector<DataType> /*_fieldCart*/)
            {
                InternalFields<DataType, ParamDataSpec<vector<DataType>>>::_paramOutput->getDataList().push_back(_fieldPol);
            }
        };
    }
}
#endif /* InternalFields.hh */