-
Notifications
You must be signed in to change notification settings - Fork 225
Implement PICMI capability for TWTS and TWEAC lasers #5561
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
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did you need to add this file? I thought we already have a TWTS implementation.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The one we have is only via background fields. There seems to be no incident field TWTS mainline yet. Correct @BeyondEspresso?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rest of file looks okay - I have to trust @BeyondEspresso that the equations are correct. Perhaps @steindev could have a second look at this file.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @BeyondEspresso Since you added now this TWTS incident field pulse, please add the option to our picongpu/include/picongpu/param/incidentField.param Lines 36 to 37 in 4a42ebb
and the examples and tests.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The TWTS implementation can be used for both background and incidentFields. With
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @PrometheusPi Just to clarify: we already have a working incident field implementation in mainline. The TWEAC-FOM setup also makes use of that. This change is about reducing boiler plate code and does not change any equations of the existing TWTSTight model. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,179 @@ | ||
| /* Copyright 2014-2025 Axel Huebl, Alexander Debus, Richard Pausch, Sergei Bastrakov | ||
| * | ||
| * This file is part of PIConGPU. | ||
| * | ||
| * PIConGPU is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * PIConGPU is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with PIConGPU. | ||
| * If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "picongpu/fields/background/templates/twtstight/TWTSTight.hpp" | ||
|
|
||
| #ifndef PARAM_COMPONENTWISE | ||
| # define PARAM_COMPONENTWISE 1 | ||
| #endif | ||
|
|
||
| namespace picongpu::fields::incidentField | ||
| { | ||
| namespace profiles | ||
| { | ||
| struct window | ||
| { | ||
| HDINLINE static float_X switchAt( | ||
| float_X const currentStep, | ||
| float_X const switchStartStep, | ||
| float_X const switchEndStep, | ||
| float_X const length) | ||
| { | ||
| /* Blackman - Nuttall window */ | ||
| constexpr float_X a0 = 0.3635819; | ||
| constexpr float_X a1 = 0.4891775; | ||
| constexpr float_X a2 = 0.1365995; | ||
| constexpr float_X a3 = 0.0106411; | ||
|
Comment on lines
+41
to
+44
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What are these constants? Could you add a comment what these magic numbers represent?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the window type. I should add a comment. |
||
| if(length < 0.0) | ||
| { | ||
| return float_X(1.0); | ||
| } | ||
| float_X const n_on = currentStep - switchStartStep; | ||
| float_X const n_off = switchEndStep - currentStep; | ||
| if((n_on < 0) || (n_off < 0)) | ||
| { | ||
| return float_X(0.0); | ||
| } | ||
| else if((n_on >= 0) && (n_on <= length)) | ||
| { | ||
| return a0 - a1 * math::cos(float_X(2.0) * PI * n_on / length / float_X(2.0)) | ||
| + a2 * math::cos(float_X(4.0) * PI * n_on / length / float_X(2.0)) | ||
| - a3 * math::cos(float_X(6.0) * PI * n_on / length / float_X(2.0)); | ||
| } | ||
| else if((switchEndStep >= switchStartStep) && (n_off >= 0) && (n_off <= length)) | ||
| { | ||
| return a0 - a1 * math::cos(float_X(2.0) * PI * n_on / length / float_X(2.0)) | ||
| + a2 * math::cos(float_X(4.0) * PI * n_on / length / float_X(2.0)) | ||
| - a3 * math::cos(float_X(6.0) * PI * n_on / length / float_X(2.0)); | ||
| } | ||
| return float_X(1.0); | ||
| } | ||
| }; | ||
|
|
||
| template<typename T_Params> | ||
| struct TWTSFunctorIncidentE | ||
| { | ||
| public: | ||
| float_X const m_currentStep; | ||
| PMACC_ALIGN(m_unitField, float3_64 const); | ||
| templates::twtstight::EField const twtsFieldE; | ||
|
|
||
| HINLINE TWTSFunctorIncidentE(float_X const currentStep, float3_64 const unitField) | ||
| : m_currentStep(currentStep) | ||
| , m_unitField(unitField) | ||
| , twtsFieldE( | ||
| T_Params::FOCUS_Y_SI, | ||
| T_Params::WAVE_LENGTH_SI, | ||
| T_Params::PULSE_DURATION_SI, | ||
| T_Params::W0_SI, | ||
| T_Params::PHI, | ||
| T_Params::BETA_0, | ||
| T_Params::TDELAY, | ||
| T_Params::AUTO_TDELAY, | ||
| T_Params::FOCUS_Z_OFFSET_SI, | ||
| T_Params::Polarization) | ||
| { | ||
| } | ||
|
|
||
| HDINLINE float3_X operator()(floatD_X const& totalCellIdx) const | ||
| { | ||
| float3_64 const invUnitField | ||
| = float3_64(1.0 / m_unitField[0], 1.0 / m_unitField[1], 1.0 / m_unitField[2]); | ||
| float3_X const amplitude = precisionCast<float_X>(T_Params::AMPLITUDE_SI * invUnitField); | ||
| return window::switchAt( | ||
| m_currentStep, | ||
| T_Params::windowStart, | ||
| T_Params::windowEnd, | ||
| T_Params::windowLength) | ||
| * amplitude * twtsFieldE(totalCellIdx, m_currentStep); | ||
| } | ||
|
|
||
| #if PARAM_COMPONENTWISE | ||
| template<uint32_t T_component> | ||
| HDINLINE float_X getComponent(floatD_X const& totalCellIdx) const | ||
| { | ||
| float_64 const invUnitField = 1.0 / m_unitField[T_component]; | ||
| float_X const amplitude = precisionCast<float_X>(T_Params::AMPLITUDE_SI * invUnitField); | ||
| return window::switchAt( | ||
| m_currentStep, | ||
| T_Params::windowStart, | ||
| T_Params::windowEnd, | ||
| T_Params::windowLength) | ||
| * amplitude * twtsFieldE.getComponent<T_component>(totalCellIdx, m_currentStep); | ||
| } | ||
| #endif | ||
| }; | ||
|
|
||
| template<typename T_Params> | ||
| struct TWTSFunctorIncidentB | ||
| { | ||
| public: | ||
| float_X const m_currentStep; | ||
| PMACC_ALIGN(m_unitField, float3_64 const); | ||
| templates::twtstight::BField twtsFieldB; | ||
|
|
||
| HINLINE TWTSFunctorIncidentB(float_X const currentStep, float3_64 const unitField) | ||
| : m_currentStep(currentStep) | ||
| , m_unitField(unitField) | ||
| , twtsFieldB( | ||
| T_Params::FOCUS_Y_SI, | ||
| T_Params::WAVE_LENGTH_SI, | ||
| T_Params::PULSE_DURATION_SI, | ||
| T_Params::W0_SI, | ||
| T_Params::PHI, | ||
| T_Params::BETA_0, | ||
| T_Params::TDELAY, | ||
| T_Params::AUTO_TDELAY, | ||
| T_Params::FOCUS_Z_OFFSET_SI, | ||
| T_Params::Polarization) | ||
| { | ||
| } | ||
|
|
||
| HDINLINE float3_X operator()(floatD_X const& totalCellIdx) const | ||
| { | ||
| float3_64 const invUnitField | ||
| = float3_64(1.0 / m_unitField[0], 1.0 / m_unitField[1], 1.0 / m_unitField[2]); | ||
| float3_X const amplitude = precisionCast<float_X>(T_Params::AMPLITUDE_SI * invUnitField); | ||
| return window::switchAt( | ||
| m_currentStep, | ||
| T_Params::windowStart, | ||
| T_Params::windowEnd, | ||
| T_Params::windowLength) | ||
| * amplitude * twtsFieldB(totalCellIdx, m_currentStep); | ||
| } | ||
|
|
||
| #if PARAM_COMPONENTWISE | ||
| template<uint32_t T_component> | ||
| HDINLINE float_X getComponent(floatD_X const& totalCellIdx) const | ||
| { | ||
| float_64 const invUnitField = 1.0 / m_unitField[T_component]; | ||
| float_X const amplitude = precisionCast<float_X>(T_Params::AMPLITUDE_SI * invUnitField); | ||
| return window::switchAt( | ||
| m_currentStep, | ||
| T_Params::windowStart, | ||
| T_Params::windowEnd, | ||
| T_Params::windowLength) | ||
| * amplitude * twtsFieldB.getComponent<T_component>(totalCellIdx, m_currentStep); | ||
| } | ||
| #endif | ||
| }; | ||
| } // namespace profiles | ||
| } // namespace picongpu::fields::incidentField | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@psychocoderHPC why does the original version seems not to work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The compiler does attempt a name lookup despite the compile-time condition. Since the
.z()do not exist in 2D, this throws an error.