Example #1
0
    DINLINE void operator()(DataBoxJ dataBoxJ,
                            const PosType pos,
                            const VelType velocity,
                            const ChargeType charge, const float_X deltaTime)
    {
        this->charge = charge;
        const float2_X deltaPos = float2_X(velocity.x() * deltaTime / cellSize.x(),
                                           velocity.y() * deltaTime / cellSize.y());
        const PosType oldPos = pos - deltaPos;
        Line<float2_X> line(oldPos, pos);
        BOOST_AUTO(cursorJ, dataBoxJ.toCursor());

        if (supp % 2 == 1)
        {
            /* odd support
             * we need only for odd supports a shift because for even supports
             * we have always the grid range [-support/2+1;support/2] if we have
             * no moving particle
             *
             * With this coordinate shift we only look to the support of one
             * particle which is not moving. Moving praticles coordinate shifts
             * are handled later (named offset_*)
             */

            /* for any direction
             * if pos> 0.5
             * shift curser+1 and new_pos=old_pos-1
             *
             * floor(pos*2.0) is equal (pos > 0.5)
             */
            float2_X coordinate_shift(
                                      float_X(math::floor(pos.x() * float_X(2.0))),
                                      float_X(math::floor(pos.y() * float_X(2.0)))
                                      );
            cursorJ = cursorJ(
                              PMacc::math::Int < 2 > (
                                                      coordinate_shift.x(),
                                                      coordinate_shift.y()
                                                      ));
            //same as: pos = pos - coordinate_shift;
            line.pos0 -= (coordinate_shift);
            line.pos1 -= (coordinate_shift);
        }

        /**
         * \brief the following three calls separate the 3D current deposition
         * into three independent 1D calls, each for one direction and current component.
         * Therefore the coordinate system has to be rotated so that the z-direction
         * is always specific.
         */

        using namespace cursor::tools;
        cptCurrent1D(cursorJ, line, cellSize.x());
        cptCurrent1D(twistVectorFieldAxes<PMacc::math::CT::Int < 1, 0 > >(cursorJ), rotateOrigin < 1, 0 > (line), cellSize.y());
        cptCurrentZ(cursorJ, line, velocity.z());
    }
Example #2
0
void TerrainEntity::constrainChild(RenderableEntity & re, PosType & pos)
{
    if (m_drawer == 0) {
        std::cout << "Constraint, but no drawer" << std::endl << std::flush;
        return;
    }
    TerrainRenderer * tr = dynamic_cast<TerrainRenderer *>(m_drawer);
    if (tr == 0) {
        std::cout << "Drawer is not terrain" << std::endl << std::flush;
        return;
    }
    WFMath::Vector<3> n;
    tr->m_terrain.getHeightAndNormal(pos.x(), pos.y(), pos.z(), n);
}
        __host__ DINLINE void operator()(
                                            const BType bField,
                                            const EType eField,
                                            PosType& pos,
                                            MomType& mom,
                                            const MassType mass,
                                            const ChargeType charge)
    {
        const float_X QoM = charge / mass;

        const float_X deltaT = DELTA_T;

        const MomType mom_minus = mom + float_X(0.5) * charge * eField * deltaT;

        Gamma gamma;
        const float_X gamma_reci = float_X(1.0) / gamma(mom_minus, mass);
        const float3_X t = float_X(0.5) * QoM * bField * gamma_reci * deltaT;
        const BType s = float_X(2.0) * t * (float_X(1.0) / (float_X(1.0) + math::abs2(t)));

        const MomType mom_prime = mom_minus + math::cross(mom_minus, t);
        const MomType mom_plus = mom_minus + math::cross(mom_prime, s);

        const MomType new_mom = mom_plus + float_X(0.5) * charge * eField * deltaT;
        mom = new_mom;

        Velocity velocity;
        const float3_X vel = velocity(new_mom, mass);

        /* IMPORTANT: 
         * use float_X(1.0)+X-float_X(1.0) because the rounding of float_X can create position from [-float_X(1.0),2.f],
         * this breaks ower definition that after position change (if statements later) the position must [float_X(0.0),float_X(1.0))
         * 1.e-9+float_X(1.0) = float_X(1.0) (this is not allowed!!!
         * 
         * If we don't use this fermi crash in this kernel in the time step n+1 in field interpolation
         */
        pos.x() += float_X(1.0) + (vel.x() * DELTA_T / CELL_WIDTH);
        pos.y() += float_X(1.0) + (vel.y() * DELTA_T / CELL_HEIGHT);
        pos.z() += float_X(1.0) + (vel.z() * DELTA_T / CELL_DEPTH);

        pos.x() -= float_X(1.0);
        pos.y() -= float_X(1.0);
        pos.z() -= float_X(1.0);

    }
Example #4
0
        __host__ DINLINE void operator()(
                                            const BType bField, /* at t=0 */
                                            const EType eField, /* at t=0 */
                                            PosType& pos, /* at t=0 */
                                            MomType& mom, /* at t=-1/2 */
                                            const MassType mass,
                                            const ChargeType charge)
    {

        /*   
             time index in paper is reduced by a half: i=0 --> i=-1/2 so that momenta are 
             at half time steps and fields and locations are at full time steps

     Here the real (PIConGPU) momentum (p) is used, not the momentum from the Vay paper (u)
     p = m_0 * u
         */
        const float_X deltaT = DELTA_T;
        const float_X factor = 0.5 * charge * deltaT;
        Gamma gamma;
        Velocity velocity;

        // first step in Vay paper:
        const float3_X velocity_atMinusHalf = velocity(mom, mass);
        //mom /(mass*mass + abs2(mom)/(SPEED_OF_LIGHT*SPEED_OF_LIGHT));
        const MomType momentum_atZero = mom + factor * (eField + math::cross(velocity_atMinusHalf, bField));

        // second step in Vay paper:
        const MomType momentum_prime = momentum_atZero + factor * eField;
        const float_X gamma_prime = gamma(momentum_prime, mass);
        //sqrtf(1.0 + abs2(momentum_prime*(1.0/(mass * SPEED_OF_LIGHT))));
        const sqrt_Vay::float3_X tau = factor / mass * bField;
        const sqrt_Vay::float_X u_star = math::dot( typeCast<sqrt_Vay::float_X>(momentum_prime), tau ) / typeCast<sqrt_Vay::float_X>( SPEED_OF_LIGHT * mass );
        const sqrt_Vay::float_X sigma = gamma_prime * gamma_prime - math::abs2( tau );
        const sqrt_Vay::float_X gamma_atPlusHalf = math::sqrt( sqrt_Vay::float_X(0.5) *
            ( sigma +
              math::sqrt( sigma * sigma +
                          sqrt_Vay::float_X(4.0) * ( math::abs2( tau ) + u_star * u_star ) )
            )
                                                    );
        const float3_X t = tau * (float_X(1.0) / gamma_atPlusHalf);
        const float_X s = float_X(1.0) / (float_X(1.0) + math::abs2(t));
        const MomType momentum_atPlusHalf = s * (momentum_prime + math::dot(momentum_prime, t) * t + math::cross(momentum_prime, t));

        mom = momentum_atPlusHalf;

        const float3_X vel = velocity(momentum_atPlusHalf, mass);

        /* IMPORTEND: 
         * use float_X(1.0)+X-float_X(1.0) because the rounding of float_X can create position from [-float_X(1.0),2.f],
         * this breaks ower definition that after position change (if statements later) the position must [float_X(0.0),float_X(1.0))
         * 1.e-9+float_X(1.0) = float_X(1.0) (this is not allowed!!!
         * 
         * If we don't use this fermi crash in this kernel in the time step n+1 in field interpolation
         */
        pos.x() += float_X(1.0) + (vel.x() * DELTA_T / CELL_WIDTH);
        pos.y() += float_X(1.0) + (vel.y() * DELTA_T / CELL_HEIGHT);
        pos.z() += float_X(1.0) + (vel.z() * DELTA_T / CELL_DEPTH);

        pos.x() -= float_X(1.0);
        pos.y() -= float_X(1.0);
        pos.z() -= float_X(1.0);

    }
Example #5
0
                __host__ DINLINE void operator( )(
                                                      const BType bField, /* at t=0 */
                                                      const EType eField, /* at t=0 */
                                                      PosType& pos, /* at t=0 */
                                                      MomType& mom, /* at t=-1/2 */
                                                      const MassType mass,
                                                      const ChargeType charge)
            {
                Gamma gammaCalc;
                Velocity velocityCalc;
                const float_X epsilon = 1.0e-6;
                const float_X deltaT = DELTA_T;

                //const float3_X velocity_atMinusHalf = velocity(mom, mass);
                const float_X gamma = gammaCalc( mom, mass );

                const MomType mom_old = mom;

                const float_X B2 = math::abs2( bField );
                const float_X B = abs( bField );

                if( B2 > epsilon )
                {
                    trigo_X sinres;
                    trigo_X cosres;
                    trigo_X arg = B * charge * deltaT / gamma;
                    math::sincos( arg, sinres, cosres );

                    mom.x() = bField.x() * bField.x() * ( eField.x() * charge * deltaT + mom_old.x() );
                    mom.y() = bField.y() * bField.y() * ( eField.y() * charge * deltaT + mom_old.y() );
                    mom.z() = bField.z() * bField.z() * ( eField.z() * charge * deltaT + mom_old.z() );

#define SUM_PLINE1(I,J,K) bField.J() * ( -levichivita(I,J,K) * gamma * eField.K() + bField.I() * ( eField.J() * charge * deltaT + mom_old.J() ) )
#define SUM_PLINE2(I,J,K) -bField.J() * ( -levichivita(I,J,K) * gamma * eField.K() + bField.I() * mom_old.J() - bField.J() * mom_old.I() )
#define SUM_PLINE3(I,J,K) bField.J() * bField.J() * gamma * eField.I() - bField.I() * bField.J() * gamma * eField.J() + levichivita(I,J,K) * mom_old.J() * bField.K() * B2

                    mom.x() += FOR_JK_NOT_I( x, y, z, SUM_PLINE1 );
                    mom.x() += float_X(cosres ) * ( FOR_JK_NOT_I( x, y, z, SUM_PLINE2 ) );
                    mom.x() += float_X(sinres ) / B * ( FOR_JK_NOT_I( x, y, z, SUM_PLINE3 ) );

                    mom.y() += FOR_JK_NOT_I( y, z, x, SUM_PLINE1 );
                    mom.y() += float_X(cosres ) * ( FOR_JK_NOT_I( y, z, x, SUM_PLINE2 ) );
                    mom.y() += float_X(sinres ) / B * ( FOR_JK_NOT_I( y, z, x, SUM_PLINE3 ) );

                    mom.z() += FOR_JK_NOT_I( z, x, y, SUM_PLINE1 );
                    mom.z() += float_X(cosres ) * ( FOR_JK_NOT_I( z, x, y, SUM_PLINE2 ) );
                    mom.z() += float_X(sinres ) / B * ( FOR_JK_NOT_I( z, x, y, SUM_PLINE3 ) );

                    mom *= float_X(1.0) / B2;
                }
                else
                {
                    mom += eField * charge * deltaT;
                }

                float3_X dr = float3_X( float_X(0.0), float_X(0.0), float_X(0.0) );
                
                // old spacial change calculation: linear step
                if( TrajectoryInterpolation == LINEAR )
                {
                    const float3_X vel = velocityCalc( mom, mass );
                    dr = float3_X( vel.x() * deltaT / CELL_WIDTH,
                                                   vel.y() * deltaT / CELL_HEIGHT,
                                                   vel.z() * deltaT / CELL_DEPTH );
                }

                // new spacial change calculation
                if( TrajectoryInterpolation == NONLINEAR )
                {
                    const float3_X vel_old = velocityCalc( mom_old, mass );
                    const float_X QoM = charge / mass;
                    const float_X B4 = B2 * B2;
                    float3_X r = pos;

                    if( B4 > epsilon )
                    {
                        trigo_X sinres;
                        trigo_X cosres;
                        trigo_X arg = B * QoM * deltaT / SPEED_OF_LIGHT;
                        math::sincos( arg, sinres, cosres );

                        r.x() = bField.x() * bField.x() * bField.x() * bField.x() * QoM
                            * ( eField.x() * QoM * deltaT * deltaT + 2.0f * ( deltaT * vel_old.x() + pos.x() ) );

#define SUM_RLINE1(I,J,K) 2.0 * bField.J() * bField.J() * bField.J() * bField.J() * QoM * pos.x() \
                    + 2.0 * bField.J() * bField.J() * bField.K() * bField.K() * QoM * pos.x() \
                    + bField.J() * bField.J() * bField.J() * ( -levichivita(I,J,K) * 2.0 * SPEED_OF_LIGHT * ( eField.K() * QoM * deltaT + vel_old.K() ) + bField.I() * QoM * deltaT * ( eField.J() * QoM * deltaT + 2.0 * vel_old.J() ) ) \
                    + bField.J() * bField.J() * ( 2.0 * SPEED_OF_LIGHT * SPEED_OF_LIGHT * eField.I() + bField.I() * bField.I() * QoM * ( eField.I() * QoM * deltaT * deltaT + 2.0 * deltaT * vel_old.I() + 4.0 * pos.I() ) + levichivita(I,J,K) * 2.0 * SPEED_OF_LIGHT * bField.K() * vel_old.J() + bField.K() * QoM * ( levichivita(I,J,K) * 2.0 * eField.J() * SPEED_OF_LIGHT * deltaT + bField.I() * bField.K() * QoM * deltaT * deltaT ) ) \
                    + bField.I() * bField.J() * ( bField.I() * bField.I() * QoM * deltaT * ( eField.J() * QoM * deltaT + 2.0 * vel_old.J() ) - levichivita(I,J,K) * 2.0 * bField.I() * SPEED_OF_LIGHT * ( eField.K() * QoM * deltaT + vel_old.K() ) - 2.0 * SPEED_OF_LIGHT * SPEED_OF_LIGHT * eField.J() )

#define SUM_RLINE2(I,J,K) - bField.J() * ( SPEED_OF_LIGHT * eField.I() * bField.J() - levichivita(I,J,K) * bField.J() * bField.J() * vel_old.K() - bField.I() * SPEED_OF_LIGHT * eField.J() - levichivita(I,J,K) * bField.J() * vel_old.K() * ( bField.I() * bField.I() + bField.K() *bField.K() ) )

#define SUM_RLINE3(I,J,K) levichivita(I,J,K) * bField.J() * ( SPEED_OF_LIGHT * eField.K() + levichivita(I,J,K) * ( bField.J() * vel_old.I() - bField.I() * vel_old.J() ) )

                        r.x() += FOR_JK_NOT_I( x, y, z, SUM_RLINE1 );
                        r.x() += float_X(cosres ) * 2.0 * SPEED_OF_LIGHT * ( FOR_JK_NOT_I( x, y, z, SUM_RLINE2 ) );
                        r.x() += float_X(sinres ) * 2.0 * SPEED_OF_LIGHT * B * ( FOR_JK_NOT_I( x, y, z, SUM_RLINE3 ) );

                        r.y() += FOR_JK_NOT_I( y, z, x, SUM_RLINE1 );
                        r.y() += float_X(cosres ) * 2.0 * SPEED_OF_LIGHT * ( FOR_JK_NOT_I( y, z, x, SUM_RLINE2 ) );
                        r.y() += float_X(sinres ) * 2.0 * SPEED_OF_LIGHT * B * ( FOR_JK_NOT_I( y, z, x, SUM_RLINE3 ) );

                        r.z() += FOR_JK_NOT_I( z, x, y, SUM_RLINE1 );
                        r.z() += float_X(cosres ) * 2.0 * SPEED_OF_LIGHT * ( FOR_JK_NOT_I( z, x, y, SUM_RLINE2 ) );
                        r.z() += float_X(sinres ) * 2.0 * SPEED_OF_LIGHT * B * ( FOR_JK_NOT_I( z, x, y, SUM_RLINE3 ) );

                        r *= float_X(0.5) / B4 / QoM;
                    }
                    else
                    {
                        r += eField * QoM * deltaT * deltaT + vel_old * deltaT;
                    }
                    dr = r - pos;
                    
                    dr *= float3_X(1.0) / cellSize;

                }

                pos += dr;
            }