Analyse a beam

Pages: 123
OK, I can now see what integral you are trying to do. The exact integral would give the correct deflection from either a reciprocal theorem or virtual work (or a very hard slog multiplying by bending-moment distribution for unit point load and some integration by parts).

However,
- you don't need to to do a numerical integration - any one of your load cases gives an EXACT solution for deflection as piecewise-continuous polynomials (point loads give cubics and UDLs give quartics).
- I did the "hard slog" approach above and came to the conclusion that it will certainly apply to the case of a simply-supported beam with zero deflection at the two ends. But what if you wanted other different (but extremely common) support conditions? Say a cantilever (one end built-in, the other free)? Or a beam supported at points other than the two ends? Wouldn't your unit-load moments (mx in the above code snippet) need changing for each?

I think you would be better using the analytical solutions for the different load cases you have included than doing a numerical integration. You would then have both accuracy and the flexibility to include other support conditions.

Maybe I took an obscure approach, but when I wrote a beam analyser for arbitrary point and linear-continuous loads, with user-specified number, position and types of support, I worked my way across the beam adding the appropriate powers of Macaulay brackets at each discontinuity in load or support reaction. At the end I was left with a small set of simultaneous linear equations to give me forces and/or moments at the supports. Solving these allowed me to write functions returning complete shear-force, bending-moment, slope and deflections at any point of the beam. I didn't do any numerical integration.
Last edited on
@lastchance
I think you may be misunderstanding what I am trying to do.
I am trying to learn C++ after many years of using BASIC. I am using the development of a program to analyse a simply supported single span beam to do this. Doing so will enable me to use many of the constructs of C++. At the moment, I have no intention to progress beam analysis further, although I may go on to design reinforced concrete, steelwork and possibly timber beams.

It is many years since I was involved in design work. For the last 40 years or so of my working life I was a project manager, so I've probably forgotten most of the mathematics I knew. I'm surprised I still remembered Simpson's Rule. I remember doing Theory of Structures, but I find it hard work now when I look at my old books and notes.

I started in structural design before the days of computers, when calculation was by slide rule and handwritten. These calculations were all hand checked by others, so the setting out had to be done accordingly. This also helped with submission to local authorities for their approval.

The program I produced in those dark days produced similar hard copy that could be hand checked and was easily understood by an Architect who would be feeding in the data. The program I produced for my Architect employer saved him a small fortune in structural engineers fees.

Surprisingly, unless he was designing framed buildings, most beams were single span. In my working life I came across few cantilever beams. The main one I can think of was in a market hall where the upper floor of part of the building was larger than below, requiring the cantilever.

However, I think many will be interested in single span solutions; if not here, then elsewhere. Whether or not I produce such a solution will depend on other influences, in particular my wife, DIY and gardening. Although I have been retired for some years, most in a similar position will tell you how time flashes by.

I am very grateful for your help and suggestions and hope that you will continue in the future as I progress (hopefully progress).

Best regards
I found an error in calculating bending moments for a type 4 load. This has now been corrected. The revised program can be found in the link below:

https://www.dropbox.com/s/drim9kouleb148f/SFBM_Build05_Dev02_07.cpp?dl=0
closed account (48T7M4Gy)
@RNBW

Interesting. I thought you might like to compare your results with the following for a point load on a 10m beam located 3.5m from the LH end. Shear force and bending moment should be the same. Slope and defelection in this set are determined by double integration. The units are just unmodified units, roughly aligned to metrication/steel:

--------------
 + GEOMETRY + 
 Tag: bm
   E: 200000
   I: 1.21e+08
--------------
   PT        X
___^_________^
   0         0
   1       500
   2      1000
   3      1500
   4      2000
   5      2500
   6      3000
   7      3500
   8      4000
   9      4500
  10      5000
  11      5500
  12      6000
  13      6500
  14      7000
  15      7500
  16      8000
  17      8500
  18      9000
  19      9500
  20     10000

----------------------------------------------------------------------
                      +++ ACTIONS ALONG BEAM +++                      
----------------------------------------------------------------------
  TAG: 
   P2 (Pt load, P = 1000, x:3500)

             END REACTIONS: Ra =     650   Rb =     350
               END MOMENTS: Ma =       0   Mb =       0
----------------------------------------------------------------------
   PT         X         V             BM          Slope         Defl'n
____^_________^_________^______________^______________^______________^
    0         0       650              0   -0.000258523              0
    1       500       650         325000   -0.000255165      -0.128702
    2      1000       650         650000   -0.000245093      -0.254046
    3      1500       650         975000   -0.000228306      -0.372676
    4      2000       650        1.3e+06   -0.000204804      -0.481233
    5      2500       650      1.625e+06   -0.000174587       -0.57636
    6      3000       650       1.95e+06   -0.000137655        -0.6547
    7      3500       650      2.275e+06   -9.40083e-05      -0.712896
    8      4000      -350        2.1e+06    -4.8812e-05       -0.74845
    9      4500      -350      1.925e+06    -7.2314e-06      -0.762311
   10      5000      -350       1.75e+06    3.07335e-05      -0.756284
   11      5500      -350      1.575e+06    6.50826e-05       -0.73218
   12      6000      -350        1.4e+06    9.58161e-05      -0.691804
   13      6500      -350      1.225e+06    0.000122934      -0.636966
   14      7000      -350       1.05e+06    0.000146436      -0.569473
   15      7500      -350         875000    0.000166322      -0.491133
   16      8000      -350         700000    0.000182593      -0.403753
   17      8500      -350         525000    0.000195248      -0.309143
   18      9000      -350         350000    0.000204287      -0.209108
   19      9500      -350         175000    0.000209711      -0.105458
   20     10000      -350              0    0.000211519   -6.45661e-16
----------------------------------------------------------------------
 
      
----------------------------------------------------------------------
Program ended with exit code: 0
closed account (48T7M4Gy)
PS you require an odd number of sections so let me know if I need to revise the input to suit that if necessary keeping in mind I show 0-20 =21
@kemort
I'm just going out, so I haven't had chance to review your output.

However, in answer to your question, the number of sections must be an odd number. This is to meet the requirements for Simpson's Rule for the calculation of deflection. Mostly I seem to see 21 sections used, but this can be a bit coarse if the span is large (e.g. for a 20m span the spacing would be 1m). I tend to use 51 or even 101 sections, but only display 11.
closed account (48T7M4Gy)
----------------------------------------------------------------------
                      +++ ACTIONS ALONG BEAM +++                      
----------------------------------------------------------------------
  TAG: 
   P2 (Pt load, P = 1000, x:3500)

             END REACTIONS: Ra =     650   Rb =     350
               END MOMENTS: Ma =       0   Mb =       0
----------------------------------------------------------------------
   PT         X         V             BM          Slope         Defl'n
____^_________^_________^______________^______________^______________^
    0         0       650              0   -0.000258523              0
    1       100       650          65000   -0.000258388     -0.0258478
    2       200       650         130000   -0.000257986     -0.0516687
    3       300       650         195000   -0.000257314      -0.077436
    4       400       650         260000   -0.000256374      -0.103123
    5       500       650         325000   -0.000255165      -0.128702
    6       600       650         390000   -0.000253688      -0.154147
    7       700       650         455000   -0.000251942       -0.17943
    8       800       650         520000   -0.000249928      -0.204526
    9       900       650         585000   -0.000247645      -0.229407
   10      1000       650         650000   -0.000245093      -0.254046
   11      1100       650         715000   -0.000242273      -0.278417
   12      1200       650         780000   -0.000239184      -0.302492
   13      1300       650         845000   -0.000235826      -0.326244
   14      1400       650         910000     -0.0002322      -0.349648
   15      1500       650         975000   -0.000228306      -0.372676
   16      1600       650       1.04e+06   -0.000224143        -0.3953
   17      1700       650      1.105e+06   -0.000219711      -0.417495
   18      1800       650       1.17e+06    -0.00021501      -0.439233
   19      1900       650      1.235e+06   -0.000210041      -0.460488
   20      2000       650        1.3e+06   -0.000204804      -0.481233
   21      2100       650      1.365e+06   -0.000199298       -0.50144
   22      2200       650       1.43e+06   -0.000193523      -0.521083
   23      2300       650      1.495e+06   -0.000187479      -0.540136
   24      2400       650       1.56e+06   -0.000181167       -0.55857
   25      2500       650      1.625e+06   -0.000174587       -0.57636
   26      2600       650       1.69e+06   -0.000167738      -0.593479
   27      2700       650      1.755e+06    -0.00016062      -0.609899
   28      2800       650       1.82e+06   -0.000153233      -0.625594
   29      2900       650      1.885e+06   -0.000145579      -0.640537
   30      3000       650       1.95e+06   -0.000137655        -0.6547
   31      3100       650      2.015e+06   -0.000129463      -0.668059
   32      3200       650       2.08e+06   -0.000121002      -0.680584
   33      3300       650      2.145e+06   -0.000112273       -0.69225
   34      3400       650       2.21e+06   -0.000103275       -0.70303
   35      3500       650      2.275e+06   -9.40083e-05      -0.712896
   36      3600      -350       2.24e+06   -8.46798e-05      -0.721829
   37      3700      -350      2.205e+06   -7.54959e-05      -0.729837
   38      3800      -350       2.17e+06   -6.64566e-05      -0.736933
   39      3900      -350      2.135e+06    -5.7562e-05      -0.743133
   40      4000      -350        2.1e+06    -4.8812e-05       -0.74845
   41      4100      -350      2.065e+06   -4.02066e-05        -0.7529
   42      4200      -350       2.03e+06   -3.17459e-05      -0.756497
   43      4300      -350      1.995e+06   -2.34298e-05      -0.759254
   44      4400      -350       1.96e+06   -1.52583e-05      -0.761187
   45      4500      -350      1.925e+06    -7.2314e-06      -0.762311
   46      4600      -350       1.89e+06    6.50826e-07      -0.762638
   47      4700      -350      1.855e+06    8.38843e-06      -0.762185
   48      4800      -350       1.82e+06    1.59814e-05      -0.760966
   49      4900      -350      1.785e+06    2.34298e-05      -0.758994
   50      5000      -350       1.75e+06    3.07335e-05      -0.756284
   51      5100      -350      1.715e+06    3.78926e-05      -0.752852
   52      5200      -350       1.68e+06     4.4907e-05      -0.748711
   53      5300      -350      1.645e+06    5.17769e-05      -0.743875
   54      5400      -350       1.61e+06    5.85021e-05       -0.73836
   55      5500      -350      1.575e+06    6.50826e-05       -0.73218
   56      5600      -350       1.54e+06    7.15186e-05      -0.725348
   57      5700      -350      1.505e+06    7.78099e-05      -0.717881
   58      5800      -350       1.47e+06    8.39566e-05      -0.709791
   59      5900      -350      1.435e+06    8.99587e-05      -0.701094
   60      6000      -350        1.4e+06    9.58161e-05      -0.691804
   61      6100      -350      1.365e+06    0.000101529      -0.681936
   62      6200      -350       1.33e+06    0.000107097      -0.671503
   63      6300      -350      1.295e+06    0.000112521      -0.660521
   64      6400      -350       1.26e+06      0.0001178      -0.649004
   65      6500      -350      1.225e+06    0.000122934      -0.636966
   66      6600      -350       1.19e+06    0.000127924      -0.624422
   67      6700      -350      1.155e+06    0.000132769      -0.611386
   68      6800      -350       1.12e+06    0.000137469      -0.597873
   69      6900      -350      1.085e+06    0.000142025      -0.583897
   70      7000      -350       1.05e+06    0.000146436      -0.569473
   71      7100      -350      1.015e+06    0.000150702      -0.554615
   72      7200      -350         980000    0.000154824      -0.539337
   73      7300      -350         945000    0.000158802      -0.523655
   74      7400      -350         910000    0.000162634      -0.507582
   75      7500      -350         875000    0.000166322      -0.491133
   76      7600      -350         840000    0.000169866      -0.474322
   77      7700      -350         805000    0.000173264      -0.457165
   78      7800      -350         770000    0.000176519      -0.439674
   79      7900      -350         735000    0.000179628      -0.421866
   80      8000      -350         700000    0.000182593      -0.403753
   81      8100      -350         665000    0.000185413      -0.385352
   82      8200      -350         630000    0.000188089      -0.366676
   83      8300      -350         595000     0.00019062      -0.347739
   84      8400      -350         560000    0.000193006      -0.328556
   85      8500      -350         525000    0.000195248      -0.309143
   86      8600      -350         490000    0.000197345      -0.289512
   87      8700      -350         455000    0.000199298      -0.269678
   88      8800      -350         420000    0.000201105      -0.249657
   89      8900      -350         385000    0.000202769      -0.229462
   90      9000      -350         350000    0.000204287      -0.209108
   91      9100      -350         315000    0.000205661       -0.18861
   92      9200      -350         280000     0.00020689      -0.167981
   93      9300      -350         245000    0.000207975      -0.147236
   94      9400      -350         210000    0.000208915       -0.12639
   95      9500      -350         175000    0.000209711      -0.105458
   96      9600      -350         140000    0.000210362     -0.0844532
   97      9700      -350         105000    0.000210868     -0.0633905
   98      9800      -350          70000    0.000211229     -0.0422844
   99      9900      -350          35000    0.000211446     -0.0211494
  100     10000      -350              0    0.000211519   -6.45661e-16

--------------
 + GEOMETRY + 
 Tag: bm
   E: 200000
   I: 1.21e+08
@Kemort
I've had to adjust my program to deal with unmodified units because it is set up to deal with distance in metres, loads in kN, shear forces in kN, bending moments in kNm and deflections in mm (+ve).

Having done this I get the following results:

RA = 650 RB = 350

Sec Shear BM Defl
1 650.00 0.00 0.00
3 650.00 65.00 0.26
5 650.00 1300.00 0.48
7 650.00 1950.00 0.66
9 -350.00 2100.00 0.75
11 -350.00 1750.00 0.76
13 -350.00 1400.00 0.69
15 -350.00 1050.00 0.57
17 -350.00 700.00 0.40
19 -350.00 350.00 0.21
21 -350.00 0.00 0.00

As you can see, the Shears and BMs are identical and the deflections are very similar (I use +ve values for deflections; you use -ve). It is good to see that the two methods of calculating deflections give such close results.

Hope this is of use to you.

Have you used a program of your own, or a commercial/proprietary program?
closed account (48T7M4Gy)
Even better I have just run your two examples which I had forgotten you posted previously:

----------------------------------------------------------------------
                      +++ ACTIONS ALONG BEAM +++                      
----------------------------------------------------------------------
      LOAD TAG: Pt load (Pt load at centre, P = 30000)
      BEAM TAG: CPP, E = 25000, I = 7.2e+09, L = 20000, dx = 1000
 END REACTIONS: Ra =   15000   Rb =   15000
   END MOMENTS: Ma =       0   Mb =       0
----------------------------------------------------------------------
   PT         X         V             BM          Slope         Defl'n
____^_________^_________^______________^______________^______________^
    0         0     15000              0    -0.00416667              0
    1      1000     15000        1.5e+07      -0.004125       -4.15278
    2      2000     15000          3e+07         -0.004       -8.22222
    3      3000     15000        4.5e+07    -0.00379167        -12.125
    4      4000     15000          6e+07        -0.0035       -15.7778
    5      5000     15000        7.5e+07      -0.003125       -19.0972
    6      6000     15000          9e+07    -0.00266667            -22
    7      7000     15000       1.05e+08      -0.002125       -24.4028
    8      8000     15000        1.2e+08        -0.0015       -26.2222
    9      9000     15000       1.35e+08   -0.000791667        -27.375
   10     10000     15000        1.5e+08              0       -27.7778
   11     11000    -15000       1.35e+08    0.000791667        -27.375
   12     12000    -15000        1.2e+08         0.0015       -26.2222
   13     13000    -15000       1.05e+08       0.002125       -24.4028
   14     14000    -15000          9e+07     0.00266667            -22
   15     15000    -15000        7.5e+07       0.003125       -19.0972
   16     16000    -15000          6e+07         0.0035       -15.7778
   17     17000    -15000        4.5e+07     0.00379167        -12.125
   18     18000    -15000          3e+07          0.004       -8.22222
   19     19000    -15000        1.5e+07       0.004125       -4.15278
   20     20000    -15000              0     0.00416667              0
----------------------------------------------------------------------
----------------------------------------------------------------------
                      +++ ACTIONS ALONG BEAM +++                      
----------------------------------------------------------------------
      LOAD TAG: UDL (UDL intensity, q = 2.5, over full length)
      BEAM TAG: CPP, E = 25000, I = 7.2e+09, L = 20000, dx = 1000
 END REACTIONS: Ra =   25000   Rb =   25000
   END MOMENTS: Ma =       0   Mb =       0
----------------------------------------------------------------------
   PT         X         V             BM          Slope         Defl'n
____^_________^_________^______________^______________^______________^
    0         0     25000              0    -0.00462963              0
    1      1000     22500      2.375e+07     -0.0045625       -4.60706
    2      2000     20000        4.5e+07    -0.00437037       -9.08333
    3      3000     17500      6.375e+07    -0.00406713       -13.3108
    4      4000     15000          8e+07    -0.00366667       -17.1852
    5      5000     12500      9.375e+07    -0.00318287       -20.6163
    6      6000     10000       1.05e+08    -0.00262963       -23.5278
    7      7000      7500     1.1375e+08    -0.00202083       -25.8571
    8      8000      5000        1.2e+08    -0.00137037       -27.5556
    9      9000      2500     1.2375e+08    -0.00069213       -28.5885
   10     10000         0       1.25e+08   -6.78168e-19       -28.9352
   11     11000     -2500     1.2375e+08     0.00069213       -28.5885
   12     12000     -5000        1.2e+08     0.00137037       -27.5556
   13     13000     -7500     1.1375e+08     0.00202083       -25.8571
   14     14000    -10000       1.05e+08     0.00262963       -23.5278
   15     15000    -12500      9.375e+07     0.00318287       -20.6163
   16     16000    -15000          8e+07     0.00366667       -17.1852
   17     17000    -17500      6.375e+07     0.00406713       -13.3108
   18     18000    -20000        4.5e+07     0.00437037       -9.08333
   19     19000    -22500      2.375e+07      0.0045625       -4.60706
   20     20000    -25000              0     0.00462963   -1.11111e-14
----------------------------------------------------------------------
Program ended with exit code: 0
Last edited on
closed account (48T7M4Gy)
It looks like we get the same answers so that's good.

I was also interested to see how the intermediate slope/deflection results compare where the slope is changing rapidly. Thanks for that.

FWIW:
1. I lean towards the dimensionless aspect because internal hard-coded conversions become a nightmare. There is a simple way to overcome it and get the user to select the units (force (mass and g maybe), rotation and length) and have a function or class to sort it all out and report the units and their derivatives. At least SI units aren't as big a problem with this as Imperial units.

2. The reason for the -ve deflection values is when you plot them they describe naturally the deflection mode for a horizontal beam, -ve being downwards Y. Global vs local coordinates come into this in the wider picture.)

3. The code is my doing and is object oriented. A Beam is a Beam object with Load objects. It's in a state of flux and that's why I took the post down because at that stage I wanted to handle the discontinuities but I've decided it's not worth the trouble - around 200-500 segments results in fairly reasonable diagrams.

4. When and if you get around to object oriented programming in C++ you'll find superposition and combined load cases are simple to implement. Influence diagrams aren't any trouble either by throwing the load into a loop, in fact it's a fairly trivial exercise once the OO work is done.

5. To show you how simple the double integration is here is the code for preparing the data for a SS beam with a general located point load. Some of it might be a bit obscure so, P_SS is a derived class of base class Load, with a constructor P_SS::P_SS(std::string aLabel, Beam aBeam, double aLoad, double aLocation)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void P_SS::P_SS::prepare_table(){
    
    double L = m_beam.L;
    double slope = 0.0;
    double deflection = 0.0;

    Ra = P * (L - a) / L;   // reaction end a
    Rb = P - Ra;            // reaction end b
    
    double x = 0.0;
    double V = 0.0;
    double BM = 0.0;
    
    double EI = m_beam.E * m_beam.I; 
    double C1 = -Ra*L*L/6 + P*(L-a)*(L-a)*(L-a)/(6*L);
    
    for(int i = 0; i <= m_beam.no_segments; ++i){
        
        x = i * m_beam.dx;
        
        if(x <= a){
            
            V = Ra;
            BM = Ra * x;
            slope = (Ra*x*x/2 + C1)/EI;
            deflection = (Ra*x*x*x/6 + C1*x)/EI;
        }
        else{ // Macaulay - to do better one day :)
            
            V = Ra - P;
            BM = Ra * x - P * (x - a);
            slope = (Ra*x*x/2 - P*(x-a)*(x-a)/2 + C1)/EI;
            deflection = (Ra*x*x*x/6 - P*(x-a)*(x-a)*(x-a)/6 + C1*x)/EI;
        }
        actions.push_back(std::make_tuple(V, BM, slope, deflection));
    }
}


Last edited on
@kemort
It's always useful if you've coded something if someone else has carried out a similar exercise and results can be compared, especially if the results agree.

I know that my C++ code it's very basic (almost BASIC-like), but I'm only a beginner at C++ and completely self-taught. I expect to make lots of mistakes and the fun is in spring them out (when I can). I shall move on to incorporating functions to cut down on the coding and also struts and possibly object programming, although I suspect that is someway off yet.

I am using the design of a simply supported beam as the vehicle to learn C++. Although it is some years (about 30) since structural design was my profession, you don't forget the basics. I come from the era when design was using pen, paper and a slide rule. So my aim is to follow a similar solution by computer with the output produced to reflect this. I did this in the early 1980s when I worked for an Architect. It was written in Amstrad Basic and was a real spaghetti effort, but it worked beautifully and saved the Architect a small fortune in Structural Engineer's fees (I was employed as a Project Manager, not structural designer). The beauty of it was that because the calculations submitted to the local authorities could have been hand written in the way that they were presented, it was not necessary to receive prior approval out the computer program (which could take weeks).

Thank you for the code you submitted. I'll study that.

@kemort

I can see your reasoning for using dimensionless figures, but I find it much easier to follow the kN, kM, m, mm route. I find it easier to understand, particularly when debugging. But we'll have to differ on this. Everybody is right and everybody is wiping, depending on how you view things.
closed account (48T7M4Gy)
@RNBW
Yep, we're all different.

Don't feel under any sort of obligation to use the OO (or any) approach. The learning curve isn't all that daunting even though there are plenty of twists and turns. The tutorial on this site is good: http://www.cplusplus.com/doc/

Where the power in it is and along with operator overloading and polymorphism which are concepts worth finding out about the process of superposition and factored loads are rendered very simply.

Good to hear from you again with your endeavors and best of luck with it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;

class Beam
{
public:
   double L, EI;
   double V0, dV0;
   Beam( double L_ = 1.0, double EI_ = 1.0 ) : L( L_ ), EI( EI_ ) {}
};

class PLoad
{
public:
   double x, W;
   PLoad( double x_ = 0.0, double W_ = 0.0 ) : x( x_ ), W( W_ ) {}
};

class CLoad
{
public:
   double xl, xr, wl, wr;
   double dx, dwdx;  
   CLoad( double XL = 0.0, double XR = 1.0, double WL = 0.0, double WR = 0.0 ) : xl( XL ), xr( XR ), wl( WL ), wr( WR )
   { 
      dx = xr - xl;
      dwdx = ( wr - wl ) / dx;
   }
};

class React
{
public:
   double x;
   char type;
   double v;
   double R;
   React( double x_ = 0.0, char T = 'F', double v_ = 0.0 ) : x( x_ ), type( T ), v( v_ ) {}
};

class Monitor
{
public:
   double x;
   double v, dvdx, S, M;
   Monitor( double X = 0.0 ) : x( X ) {}
};

//

Beam beam;
vector<PLoad> load;
vector<CLoad> cont;
vector<React> react;
vector<Monitor> pt;

void prob();
void init();
void calc();
void outp();
double Defl( double x );
double Grad( double x );
double BM( double x );
double SF( double x );
double Vnr( double x );
double dVnr( double x );
double Mnr( double x );
double Snr( double x );
double loadInt( double x, int p );
double Mac( double x, double x0, int n );

//

int main()
{
   init();
   prob();
   calc();
   outp();
}

//

void prob()
{
   // Beam
   double L = 20000.0, E = 25000.0, I = 7.2e9;
   beam = Beam( L, E * I );

   // Loads
   load.push_back( PLoad( L / 2.0, 3.0e4 )   ); // pt
// cont.push_back( CLoad( 0.0, L, 2.5, 2.5 ) ); // UDL

   // Reactions
   react.push_back( React( 0.0, 'F', 0.0 ) );
   react.push_back( React( L  , 'F', 0.0 ) );

   double x1 = 0.0, x2 = L;
   int nx = 20;
   double dx = ( x2 - x1 ) / nx;
   for ( int i = 0; i <= nx; i++ ) pt.push_back( Monitor( x1 + i * dx ) );
}

//

void init()
{
   beam = Beam( 1.0, 1.0 );
   load.clear();
   cont.clear();
   react.clear();
   pt.clear();
}

//

void calc()
{
   int i, ii, ibig, j, m, n;
   double f, big, temp, xm, xn;
   int nR = react.size();
   int size = nR + 2;
   vector< vector<double> > A( size, vector<double>( size, 0.0 ) );
   vector<double> b( size, 0.0 );
   vector<double> x( size, 0.0 );

   // Load
   i = 0;
   for ( n = 0; n < nR; n++ )
   {
      if ( react[n].type == 'F' ) A[i][n+2] = 1.0;
   }
   b[i] = Snr( beam.L );

   // Moment
   i = 1;
   for ( n = 0; n < nR; n++ )
   {
      if ( react[n].type == 'M' ) A[i][n+2] = 1.0;
      if ( react[n].type == 'F' ) A[i][n+2] = -( beam.L - react[n].x );
   }
   b[i] = Mnr( beam.L );

   // Constraints
   for ( m = 0; m < nR; m++ )
   {
      xm = react[m].x;
      i = m + 2;
      if ( react[m].type == 'F' )
      {
         A[i][0] = 1.0;
         A[i][1] = xm;
         for ( n = 0; n < nR; n++ ) 
         {
            xn = react[n].x;
            j = n + 2;
            if ( react[n].type == 'M' ) A[i][j] =  Mac( xm, xn, 2 );
            if ( react[n].type == 'F' ) A[i][j] = -Mac( xm, xn, 3 );
         }
         b[i] = beam.EI * react[m].v - Vnr( xm );
      }
      if ( react[m].type == 'M' )
      {
         A[i][0] = 0.0;
         A[i][1] = 1.0;
         for ( n = 0; n < nR; n++ ) 
         {
            xn = react[n].x;
            j = n + 2;
            if ( react[n].type == 'M' ) A[i][j] =  Mac( xm, xn, 1 );
            if ( react[n].type == 'F' ) A[i][j] = -Mac( xm, xn, 2 );
         }
         b[i] = beam.EI * react[m].v - dVnr( xm );
      }
   }

   // Solve
   // Norm rows
   for ( i = 0; i < size; i++ )
   {
      big = abs( A[i][0] );
      for ( j = 1;  j < size; j++ ) big = max( abs( A[i][j] ), big );
      for ( j = 0;  j < size; j++ ) A[i][j] = A[i][j] / big;
      b[i] = b[i] / big;
   }

   // Triangular
   for ( i = 0; i < size - 1; i++ )
   {
      // Make A[i][i] largest on diagonal or below
      big = abs( A[i][i] );
      ibig = i;
      for ( ii = i + 1;  ii < size; ii++ )
      {
         temp = abs( A[ii][i] );
         if ( temp > big)
         {
            big = temp;
            ibig = ii;
         }
      }
      if ( ibig != i )
      {
         for ( j = i; j < size; j++ ) swap( A[i][j], A[ibig][j] );
         swap( b[i], b[ibig] );
      }

      // Pivot
      for ( ii = i + 1; ii < size; ii++ )
      {
         f = A[ii][i] / A[i][i];
         for ( j = 0; j < size; j++ ) A[ii][j] -= f * A[i][j];
         b[ii] -= f * b[i];
      }
   }

   // Back-sub
   for ( i = size - 1; i >= 0; i-- )
   {
      x[i] = b[i];
      for ( j = i + 1; j < size; j++ ) x[i] -= A[i][j] * x[j];
      x[i] /= A[i][i];
   }

   beam.V0  = x[0];
   beam.dV0 = x[1];
   for ( n = 0; n < nR; n++ ) 
   {
      i = n + 2;
      react[n].R = x[i];
   }
}

//

void outp()
{
   #define SP << setw( 15 ) <<

   for ( int n = 0; n < pt.size(); n++ )
   {
      double x = pt[n].x;
      pt[n].v    = Defl( x );
      pt[n].dvdx = Grad( x );
      pt[n].S    = SF  ( x );
      pt[n].M    = BM  ( x );
   }

   cout << "Beam:\n";
   cout << "  L:  " << beam.L  << '\n';
   cout << "  EI: " << beam.EI << '\n';
   cout << '\n';

   cout << "Point loads:\n" SP "x" SP "Value" << '\n';
   for ( int i = 0; i < load.size(); i++ ) cout SP load[i].x SP load[i].W << '\n';
   cout << '\n';

   cout << "Cont. loads:\n" SP "xl" SP "xr" SP "wl" SP "wr" << '\n';
   for ( int i = 0; i < cont.size(); i++ ) cout SP cont[i].xl SP cont[i].xr SP cont[i].wl SP cont[i].wr << '\n';
   cout << '\n';

   cout << "Reactions:\n" SP "x" SP "Type" SP "Value" << '\n';
   for ( int i = 0; i < react.size(); i++ ) cout SP react[i].x SP react[i].type SP react[i].R << '\n';
   cout << '\n';

   cout << "Monitors:\n" SP "Num" SP "x" SP "S" SP "M" SP "slope" SP "down" << '\n';
   for ( int i = 0; i < pt.size(); i++ )
      cout SP i SP pt[i].x SP pt[i].S SP pt[i].M  SP pt[i].dvdx SP pt[i].v << '\n';
}

//

double Defl( double x )
{
   double val = Vnr( x );
   for ( int n = 0; n < react.size(); n++ )
   {
      if ( react[n].type == 'M' ) val += react[n].R * Mac( x, react[n].x, 2 );
      if ( react[n].type == 'F' ) val -= react[n].R * Mac( x, react[n].x, 3 );
   }
   val += beam.dV0 * x + beam.V0;
   return val / beam.EI;
}

//

double Grad( double x )
{
   double val = dVnr( x );
   for ( int n = 0; n < react.size(); n++ )
   {
      if ( react[n].type == 'M' ) val += react[n].R * Mac( x, react[n].x, 1 );
      if ( react[n].type == 'F' ) val -= react[n].R * Mac( x, react[n].x, 2 );
   }
   val += beam.dV0;
   return val / beam.EI;
}

//

double BM( double x )
{
   double val = Mnr( x );
   for ( int n = 0; n < react.size(); n++ )
   {
      if ( react[n].type == 'M' ) val -= react[n].R * Mac( x, react[n].x, 0 );
      if ( react[n].type == 'F' ) val += react[n].R * Mac( x, react[n].x, 1 );
   }
   return val;
}

//

double SF( double x )
{
   double val = Snr( x );
   for ( int n = 0; n < react.size(); n++ )
   {
      if ( react[n].type == 'F' ) val -= react[n].R * Mac( x, react[n].x, 0 );
   }
   return val;
}

//

double Vnr( double x )  
{
   return loadInt( x, 4 );
}

//

double dVnr( double x ) 
{
   return loadInt( x, 3 );
}

//

double Mnr( double x )
{
   return -loadInt( x, 2 );
}

//

double Snr( double x )
{
   return loadInt( x, 1 );
}

//

double loadInt( double x, int p )  // pth integral of load
{
   double val = 0.0;
   for ( int n = 0; n < load.size(); n++ ) 
   {
      val += load[n].W * Mac( x, load[n].x, p - 1 );
   }
   for ( int n = 0; n < cont.size(); n++ )
   {
      val += cont[n].wl   * ( Mac( x, cont[n].xl, p     ) - Mac( x, cont[n].xr, p     ) );
      val += cont[n].dwdx * ( Mac( x, cont[n].xl, p + 1 ) - Mac( x, cont[n].xr, p + 1 ) - cont[n].dx * Mac( x, cont[n].xr, p ) );
   }
   return val;
}

//

double Mac( double x, double x0, int n )  // Macaulay bracket & integrals
{
   double xx = x - x0;
   
   if ( xx < 0 ) return 0.0;
   if ( n == 0 ) return 1.0;

   double val = xx;
   for ( int i = 2; i <= n; i++ ) val *= xx / i;
   return val;
}

Cases as for @kemort's last output.

Note that I am using the opposite sign convention for shear force, slope and deflection - sorry!


Beam:
  L:  20000
  EI: 1.8e+14

Point loads:
              x          Value
          10000          30000

Cont. loads:
             xl             xr             wl             wr

Reactions:
              x           Type          Value
              0              F          15000
          20000              F          15000

Monitors:
            Num              x              S              M          slope           down
              0              0         -15000              0     0.00416667              0
              1           1000         -15000        1.5e+07       0.004125        4.15278
              2           2000         -15000          3e+07          0.004        8.22222
              3           3000         -15000        4.5e+07     0.00379167         12.125
              4           4000         -15000          6e+07         0.0035        15.7778
              5           5000         -15000        7.5e+07       0.003125        19.0972
              6           6000         -15000          9e+07     0.00266667             22
              7           7000         -15000       1.05e+08       0.002125        24.4028
              8           8000         -15000        1.2e+08         0.0015        26.2222
              9           9000         -15000       1.35e+08    0.000791667         27.375
             10          10000          15000        1.5e+08    6.78168e-19        27.7778
             11          11000          15000       1.35e+08   -0.000791667         27.375
             12          12000          15000        1.2e+08        -0.0015        26.2222
             13          13000          15000       1.05e+08      -0.002125        24.4028
             14          14000          15000          9e+07    -0.00266667             22
             15          15000          15000        7.5e+07      -0.003125        19.0972
             16          16000          15000          6e+07        -0.0035        15.7778
             17          17000          15000        4.5e+07    -0.00379167         12.125
             18          18000          15000          3e+07         -0.004        8.22222
             19          19000          15000        1.5e+07      -0.004125        4.15278
             20          20000              0              0    -0.00416667   -1.11111e-14




Beam:
  L:  20000
  EI: 1.8e+14

Point loads:
              x          Value

Cont. loads:
             xl             xr             wl             wr
              0          20000            2.5            2.5

Reactions:
              x           Type          Value
              0              F          25000
          20000              F          25000

Monitors:
            Num              x              S              M          slope           down
              0              0         -25000              0     0.00462963              0
              1           1000         -22500      2.375e+07      0.0045625        4.60706
              2           2000         -20000        4.5e+07     0.00437037        9.08333
              3           3000         -17500      6.375e+07     0.00406713        13.3108
              4           4000         -15000          8e+07     0.00366667        17.1852
              5           5000         -12500      9.375e+07     0.00318287        20.6163
              6           6000         -10000       1.05e+08     0.00262963        23.5278
              7           7000          -7500     1.1375e+08     0.00202083        25.8571
              8           8000          -5000        1.2e+08     0.00137037        27.5556
              9           9000          -2500     1.2375e+08     0.00069213        28.5885
             10          10000              0       1.25e+08    6.78168e-19        28.9352
             11          11000           2500     1.2375e+08    -0.00069213        28.5885
             12          12000           5000        1.2e+08    -0.00137037        27.5556
             13          13000           7500     1.1375e+08    -0.00202083        25.8571
             14          14000          10000       1.05e+08    -0.00262963        23.5278
             15          15000          12500      9.375e+07    -0.00318287        20.6163
             16          16000          15000          8e+07    -0.00366667        17.1852
             17          17000          17500      6.375e+07    -0.00406713        13.3108
             18          18000          20000        4.5e+07    -0.00437037        9.08333
             19          19000          22500      2.375e+07     -0.0045625        4.60706
             20          20000              0              0    -0.00462963              0
@last chance
Thanks very much for the code. It's well beyond my capabilities at the moment, but I'll run it with a few of my own examples to compare with my own code and have a good play with it. Who knows what may come out of it!

Best regards.
closed account (48T7M4Gy)
Looks like they are the same @lastchance. Very comforting. Thanks for that.

Except when the signs are in the wrong place, whether they are -ve or +ve doesn't matter much from my point of view.

I certainly don't want to try and convince anyone that there is only one way but FWIW I'm following the convention and reasons for it in a current textbook 'Mechanics of Materials' Goodno, Gere 8th edition, Chapter 9. Even with that there are some 'discontinuities'.

I like the Macaulay/integration function @lastchance. It's 'disturbingly' simple. The pattern is obvious when you write the various equations but implementing it is a valuable step, just in avoiding algebraic errors by letting the machine work it out.

Cheers :)
Hi @kemort,

I'm not bothered by sign conventions either; it's a matter of personal choice. Where there's a discontinuity in shear force at reaction points I'm evaluating it on the "plus" side - that's somewhat arbitrary too (but making S go to 0 at L+ adds a check on the force balance).

In case my reactions calculator (function calc()) looks ridiculously complicated it's because I'm allowing for other than simply-supported beams. Just a third support - in the centre, say, would make it statically indeterminate and you would need conditions other than just balancing forces and moments to solve.

It was put together in a hurry from code originally written in javascript, so any errors - let me know. I need to put together some proper input / output file routines still.

Last edited on
closed account (48T7M4Gy)
Yep I gathered end-fixity is taken into account in your program. I haven't looked at it closely but I read it as a matrix solver in that context so I didn't see anything ridiculous. :)

The discontinuities in the shear force diagram are indeed a nuisance. I found I needed 200-500 points to make the plotted diagram 'look' right. It doesn't take long to process but its annoying. The saving grace for not bothering is a design program that sizes members isn't interested in the prettiness, just discrete points. So if there are enough segments then it's probably OK to leave it at 20-50 segments.

Thanks for showing us - and if you decide to go totally OO and overload the arithmetic operators you'll be glad of Java -> C++ conversion

@kemort and @lastchance

Well I am glad I started this thread. Not only have I learned a great deal, it's also got you two talking about a subject that interests me. Maybe some others may join in also. There must be loads of structural engineers out there.
Pages: 123