public void AddInternalDistributedLoad(InternalDistributedLoad3D load)
 {
     _internalDistributedLoads.Add(load);
 }
        protected InternalDistributedLoad3D GetDistributedLoadFromReaction(InternalDistributedLoad3D load)
        {
            if (GetDistanceFromPointToLine2D(EndI, EndJ, load.StartLoad.Location) <= FUZZDISTANCE)
            {
                if (GetDistanceFromPointToLine2D(EndI, EndJ, load.EndLoad.Location) <= FUZZDISTANCE)
                {
                    //If both the start and end points are on the line that defines the element (within a fuzz distance), we can try to add it
                    Vector3D     Vector_I_J     = EndJ - EndI;
                    UnitVector3D UnitVector_I_J = Vector_I_J.Normalize();

                    Vector3D Vector_I_StartLoad = load.StartLoad.Location - EndI;
                    Vector3D Vector_I_EndLoad   = load.EndLoad.Location - EndI;

                    double StartLoadProjection = Math.Abs(Vector_I_StartLoad.DotProduct(UnitVector_I_J));
                    double EndLoadProjection   = Math.Abs(Vector_I_EndLoad.DotProduct(UnitVector_I_J));
                    double ElementLength       = Math.Abs(Vector_I_J.DotProduct(UnitVector_I_J));

                    PointLoad3D StartLoad = null;
                    PointLoad3D EndLoad   = null;

                    //Check start load

                    if (Math.Sign(Vector_I_StartLoad.DotProduct(UnitVector_I_J)) ==
                        Math.Sign(Vector_I_J.DotProduct(UnitVector_I_J)))
                    {
                        //The start load position is towards the J end from the I end
                        if (Math.Sign(Vector_I_EndLoad.DotProduct(UnitVector_I_J)) ==
                            Math.Sign(Vector_I_J.DotProduct(UnitVector_I_J)))
                        {
                            //The end load position is towards the J end from the I end
                            if (Math.Abs(Vector_I_StartLoad.DotProduct(UnitVector_I_J)) <
                                Math.Abs(Vector_I_EndLoad.DotProduct(UnitVector_I_J)))
                            {
                                //the start load is before the end load
                                if (Math.Abs(Vector_I_StartLoad.DotProduct(UnitVector_I_J)) <
                                    Math.Abs(Vector_I_J.DotProduct(UnitVector_I_J)))
                                {
                                    //The start load is before the end of the member
                                    StartLoad = load.StartLoad; //The start load is acceptable

                                    if (Math.Abs(Vector_I_EndLoad.DotProduct(UnitVector_I_J)) <=
                                        Math.Abs(Vector_I_J.DotProduct(UnitVector_I_J)))
                                    {
                                        //The end load is before or equal to the end of the member
                                        EndLoad = load.EndLoad;
                                    }
                                    else
                                    {
                                        //The end load is beyond the end of the member, so we must interpolate
                                        EndLoad = InterpolatePointLoad(StartLoadProjection, load.StartLoad,
                                                                       EndLoadProjection, load.EndLoad, EndJ, ElementLength);
                                    }
                                }

                                //Otherwise, we don't add the load (the start load is off of the member and the end load is beyond the start load)
                            }
                            else
                            {
                                //The end load is before the start load
                                //We have already determined that the end load is in the same direction as the J end, so it is definitely on the element
                                StartLoad = load.EndLoad;

                                if (Math.Abs(Vector_I_StartLoad.DotProduct(UnitVector_I_J)) <=
                                    Math.Abs(Vector_I_J.DotProduct(UnitVector_I_J)))
                                {
                                    //The start load is before or equal to the end of the member
                                    EndLoad = load.StartLoad;
                                }
                                else
                                {
                                    //The start load is beyond the end of the member, so we must interpolate
                                    EndLoad = InterpolatePointLoad(EndLoadProjection, load.EndLoad, StartLoadProjection,
                                                                   load.StartLoad, EndJ, ElementLength);
                                }
                            }
                        }
                        else
                        {
                            //The end load position is away from the J end, or is at the I end
                            if (Math.Sign(Vector_I_EndLoad.DotProduct(UnitVector_I_J)) == 0)
                            {
                                //The end load is at the I end
                                StartLoad = load.EndLoad;
                            }
                            else
                            {
                                //The end load is before the I end, so we must interpoate
                                StartLoad = InterpolatePointLoad(0, load.EndLoad,
                                                                 EndLoadProjection + StartLoadProjection, load.StartLoad, EndI, EndLoadProjection);
                            }


                            if (Math.Abs(Vector_I_StartLoad.DotProduct(UnitVector_I_J)) <=
                                Math.Abs(Vector_I_J.DotProduct(UnitVector_I_J)))
                            {
                                //If the start load is less than or equal to the end of the member
                                EndLoad = load.StartLoad;
                            }
                            else
                            {
                                //The start load is beyond the end of the member, so we need to interpolate
                                EndLoad = InterpolatePointLoad(0, load.EndLoad, EndLoadProjection + StartLoadProjection,
                                                               load.StartLoad, EndJ, EndLoadProjection + ElementLength);
                            }
                        }
                    }
                    else
                    {
                        //The start load projecttion is opposite of the member direction (i.e. the start load is before the I end), or is at the I end
                        if (Math.Sign(Vector_I_EndLoad.DotProduct(UnitVector_I_J)) ==
                            Math.Sign(Vector_I_J.DotProduct(UnitVector_I_J)))
                        {
                            //The end load position is towards the J end from the I end
                            if (Vector_I_StartLoad.DotProduct(UnitVector_I_J) == 0)
                            {
                                //The start load is at end I
                                StartLoad = load.StartLoad;
                            }
                            else
                            {
                                //The start load is befoore end I, so we need to interpolate
                                StartLoad = InterpolatePointLoad(0, load.StartLoad,
                                                                 StartLoadProjection + EndLoadProjection, load.EndLoad, EndI, StartLoadProjection);
                            }

                            if (Math.Abs(Vector_I_EndLoad.DotProduct(UnitVector_I_J)) <=
                                Math.Abs(Vector_I_J.DotProduct(UnitVector_I_J)))
                            {
                                //The end load is before or equal to the end of the member
                                EndLoad = load.EndLoad;
                            }
                            else
                            {
                                //The end load is beyond the end of the member, so we must interpolate
                                EndLoad = InterpolatePointLoad(0, load.StartLoad,
                                                               StartLoadProjection + EndLoadProjection, load.EndLoad, EndJ,
                                                               StartLoadProjection + ElementLength);
                            }
                        }
                    }

                    if (StartLoad != null && EndLoad != null)
                    {
                        InternalDistributedLoad3D newIDL3D =
                            new InternalDistributedLoad3D(StartLoad, EndLoad, load.Source);
                        return(newIDL3D);
                    }
                }
            }

            return(new InternalDistributedLoad3D(new PointLoad3D(EndI, 0, 0, 0, 0, 0, 0, LoadPattern.Dead),
                                                 new PointLoad3D(EndJ, 0, 0, 0, 0, 0, 0, LoadPattern.Dead), load.Source));
        }