Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Implement arbitrary field sequences #14

Open
wants to merge 13 commits into
base: dev
Choose a base branch
from
9 changes: 6 additions & 3 deletions Particle_Simulation/Fields/FieldList.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
class SincField;
template <typename prec>
class ModulatedSincField;
template <typename prec>
class SequenceField;

template <typename Field>
class FieldTraits;
Expand All @@ -47,18 +49,19 @@ namespace Properties
using namespace std::literals::string_view_literals;
}
/// <summary> Values that represent the used fields. </summary>
enum class IField {Field_Zero=1,Field_Constant, Field_Sinusoidal, Field_Lissajous,Field_Triangular, Field_Rectangular,Field_Sinc ,Field_Modsinc};
enum class IField {Field_Zero=1,Field_Constant, Field_Sinusoidal, Field_Lissajous,Field_Triangular, Field_Rectangular,Field_Sinc ,Field_Modsinc,Field_Sequence};

/// <summary> Map used to change the IField enum to a string and vice versa. </summary>
inline constexpr MyCEL::static_map<IField, std::string_view, 8> IFieldMap { { {
inline constexpr MyCEL::static_map<IField, std::string_view, 9> IFieldMap { { {
{ IField::Field_Zero, "none"sv },
{ IField::Field_Constant, "constant"sv },
{ IField::Field_Sinusoidal, "sinusoidal"sv },
{ IField::Field_Lissajous, "lissajous"sv },
{ IField::Field_Triangular,"triangular"sv },
{ IField::Field_Rectangular,"rectangular"sv },
{ IField::Field_Sinc,"sinc"sv },
{ IField::Field_Modsinc,"modsinc"sv }
{ IField::Field_Modsinc,"modsinc"sv },
{ IField::Field_Sequence,"sequence"sv },
} }};
inline constexpr auto IFieldValues{ IFieldMap.get_key_array() };

Expand Down
1 change: 1 addition & 0 deletions Particle_Simulation/Fields/Fields.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ set(H_FILES_Fields Fields/FieldList.h
Fields/RectangularField.h
Fields/SincField.h
Fields/ModulatedSincField.h
Fields/SequenceField.h
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change to hpp file

)
source_group("Fields" FILES ${CPP_FILES_Fields} ${INL_FILES_Fields} ${H_FILES_Fields})
set(CPP_FILES ${CPP_FILES} ${CPP_FILES_Fields})
Expand Down
191 changes: 191 additions & 0 deletions Particle_Simulation/Fields/SequenceField.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@

#ifndef INC_SequenceField_H
#define INC_SequenceField_H
///---------------------------------------------------------------------------------------------------
#pragma once

#include <MyCEL/math/math_constants.h>

#include <cmath>
#include <exception>
#include <type_traits>
#include <variant>
#include <vector>

#include "Properties/FieldProperties.h"
#include "SDEFramework/GeneralField.h"

//Field Includes
#include "Fields/ConstantField.h"
#include "Fields/LissajousField.h"
#include "Fields/ModulatedSincField.h"
#include "Fields/RectangularField.h"
#include "Fields/SincField.h"
#include "Fields/SinusoidalField.h"
#include "Fields/TriangularField.h"
#include "Fields/ZeroField.h"

template <class... Ts>
struct SeqFieldOverload : Ts...
{
using Ts::operator()...;
};
template <class... Ts>
SeqFieldOverload(Ts...) -> SeqFieldOverload<Ts...>;

template <typename precision>
class SequenceField : public GeneralField<SequenceField<precision>>
{
public:
using ThisClass = SequenceField<precision>;
using Precision = precision;
using Base = GeneralField<ThisClass>;
using Traits = typename Base::Traits;
using FieldProperties = typename Traits::FieldProperties;
using FieldVector = typename Traits::FieldVector;
using FieldParams = typename Traits::FieldParameters;

template <SequenceFieldProp::ISequenceFields Field>
using type = typename Selectors::SequenceFieldSelector<Field>::template FieldParameters<Precision>;

template <SequenceFieldProp::ISequenceFields Field>
using ExFieldtype = typename Selectors::SequenceFieldSelector<Field>::template FieldType<Precision>;

using impl_field = std::variant<ZeroField<precision>, ConstantField<precision>, SinusoidalField<precision>,
LissajousField<precision>, TriangularField<precision>, RectangularField<precision>,
SincField<precision>, ModulatedSincField<precision>>;

private:
size_t step = 1;
FieldParams params;
std::vector<size_t> cumulatedSteps;
std::vector<impl_field> exfield;

protected:
public:
constexpr SequenceField(const typename Traits::FieldParameters &input)
: params(input)
{
size_t lastVal = 0;
for (size_t i = 0; i < input.stepsPerField.size(); i++) {
cumulatedSteps.push_back(input.stepsPerField[i] + lastVal);
lastVal = cumulatedSteps[i];
}
for (const auto &value : input.fields) {
auto currentFieldVar = value.variant;

std::visit(
SeqFieldOverload{
[this](type<SequenceFieldProp::ISequenceFields::Field_Zero> & Fieldparams) {
ExFieldtype<SequenceFieldProp::ISequenceFields::Field_Zero> seqfield(Fieldparams);
impl_field tmp = seqfield;
(this->exfield).push_back(tmp);
},
[this](type<SequenceFieldProp::ISequenceFields::Field_Constant> &Fieldparams) {
ExFieldtype<SequenceFieldProp::ISequenceFields::Field_Constant> seqfield(Fieldparams);
impl_field tmp = seqfield;
(this->exfield).push_back(tmp);
},
[this](type<SequenceFieldProp::ISequenceFields::Field_Sinusoidal> &Fieldparams) {
ExFieldtype<SequenceFieldProp::ISequenceFields::Field_Sinusoidal> seqfield(Fieldparams);
impl_field tmp = seqfield;
(this->exfield).push_back(tmp);
},
[this](type<SequenceFieldProp::ISequenceFields::Field_Lissajous> &Fieldparams) {
ExFieldtype<SequenceFieldProp::ISequenceFields::Field_Lissajous> seqfield(Fieldparams);
impl_field tmp = seqfield;
(this->exfield).push_back(tmp);
},
[this](type<SequenceFieldProp::ISequenceFields::Field_Triangular> &Fieldparams) {
ExFieldtype<SequenceFieldProp::ISequenceFields::Field_Triangular> seqfield(Fieldparams);
impl_field tmp = seqfield;
(this->exfield).push_back(tmp);
},
[this](type<SequenceFieldProp::ISequenceFields::Field_Rectangular> &Fieldparams) {
ExFieldtype<SequenceFieldProp::ISequenceFields::Field_Rectangular> seqfield(Fieldparams);
impl_field tmp = seqfield;
(this->exfield).push_back(tmp);
},
[this](type<SequenceFieldProp::ISequenceFields::Field_Sinc> &Fieldparams) {
ExFieldtype<SequenceFieldProp::ISequenceFields::Field_Sinc> seqfield(Fieldparams);
impl_field tmp = seqfield;
(this->exfield).push_back(tmp);
},
[this](type<SequenceFieldProp::ISequenceFields::Field_Modsinc> &Fieldparams) {
ExFieldtype<SequenceFieldProp::ISequenceFields::Field_Modsinc> seqfield(Fieldparams);
impl_field tmp = seqfield;
(this->exfield).push_back(tmp);
},
},
currentFieldVar);
}
};

inline FieldVector getCurrentField(impl_field &field, const Precision &time)
{
switch (field.index()) {
case 0:{
return std::get<ZeroField<precision>>(field).getField(time);
break;}
case 1:{
return std::get<ConstantField<precision>>(field).getField(time);
break;}
case 2:{
return std::get<SinusoidalField<precision>>(field).getField(time);
break;}
case 3:{
return std::get<LissajousField<precision>>(field).getField(time);
break;}
case 4:{
return std::get<TriangularField<precision>>(field).getField(time);
break;}
case 5:{
return std::get<RectangularField<precision>>(field).getField(time);
break;}
case 6:{
return std::get<SincField<precision>>(field).getField(time);
break;}
case 7:{
return std::get<ModulatedSincField<precision>>(field).getField(time);
break;}
default:
throw std::runtime_error{ "getCurrentField: unknown active variant type" };
break;
}
}
constexpr SequenceField(const FieldProperties &pars)
: SequenceField(pars.template getFieldParameters<Traits::Field_type>()){

};

inline FieldVector getField(const Precision &time)
{
for (size_t i = 0; i < exfield.size(); i++) {
if (step <= cumulatedSteps[i]) {
step++;
return getCurrentField(exfield[i], time);
}
else if (step > cumulatedSteps.back()) {
step=2;
return getField(time);
}
}
throw std::runtime_error{ "no Valid field" };
}
};

template <typename prec>
class FieldTraits<SequenceField<prec>>
{
public:
using Precision = prec;
using FieldProperties = Properties::FieldProperties<Precision>;
using FieldVector = Eigen::Matrix<Precision, 3, 1>;
using FieldVectorStdAllocator = std::allocator<FieldVector>;
using FieldParameters = ::Properties::Fields::Sequence<Precision>;
static constexpr auto Field_type = ::Properties::IField::Field_Sequence;
};

#endif // INC_SequenceField_H
// end of LissajousField.h
///---------------------------------------------------------------------------------------------------
3 changes: 3 additions & 0 deletions Particle_Simulation/Fields/ZeroField.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ class ZeroField : public GeneralField<ZeroField<precision>>
FieldParams params;

public:
ZeroField(const typename Traits::FieldParameters &input)
: params(input)
{};
ZeroField(const FieldProperties & par) : params(par.template getFieldParameters<Traits::Field_type>()) {};
inline auto getField(const precision) const { return FieldVector::Zero(); };

Expand Down
1 change: 1 addition & 0 deletions Particle_Simulation/Properties/Fields/AllFields.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
#include "Triangular.hpp"
#include "Sinc.hpp"
#include "ModulatedSinc.hpp"
#include "Sequence.hpp"

#endif //SPHYS_PROPERTIES_FIELDS_ALL
Loading