Apply loads by array

Hi

Is it possible to apply loads using arrays without having to use loops?

Please see my small example code below:

+prog aqua urs:35.1
    head Materials
    MAT 1 E 35000 mue 0.3 gam 25
    SREC 1 H 1000[mm] B 500[mm] MNO 1

END
+prog sofimshc urs:35.2
    head Geometry
    SYST 2D GDIV 200000 GDIR NEGY
    CTRL MESH 1
    UNIT 5

    loop#i 10
        SPT #i+1 X #i*2000[mm] Y 0
    endloop

    loop#i 9
        SLN #i+1 NPA #i+1 NPE #i+2 SNO 1 GRP #i+1
    endloop

    SPT -1 fix pp
    SPT -10 fix pp


END
+prog sofiload urs:35.3
    head Load
        let#mygrp 1,2,3,4

        LC 1 TYPE 'NONE'
                LINE REF BGRP #mygrp PROJ YY WIDE 10  P1 10 X1  0 Y1 5[m] $$
                                                            X2 10[m] Y2 5[m]

END

Here I’d like to apply loads to #mygrp I have tried multiple variations e.g. #mygrp(:) (#mygrp(0 3 1)) etc. but nothing works.

I figured out that this can be done by using $ variables instead of #. As such, a string containing the exact text from the $ variable is input.

Thereby, the sofiload program looks like this instead:

+prog sofiload
    head Load
        #define mygrp=1,2,3,4

        LC 1 TYPE 'NONE'
                LINE REF BGRP $(mygrp) PROJ YY WIDE 10  P1 10 X1 0[m]  Y1 5[m] $$
                                                              X2 10[m] Y2 5[m]
END

This however, leads to another problem.
I can’t have the $ variable hardcoded and I need to define it through a loop.

As per the manual §2.9.1:

Definitions like $(A$(INDEX)) are allowed

But I can’t for the life of me get indexing to work.

So… How do I define a $ variable in a loop?

why dont u want to use loops? maybe try use array length as count of loops

 +prog sofiload
 head loads
 let#mygrp 1,2,3,4
 lc 1 none
   loop#i mygrp
     line ref bgrp #mygrp(#i) proj yy wide 10 p1 10 x1 0[m] y1 5[m] x2 10[m] y2 5[m] 
   endloop
 end

Loops are ineffective and should be avoided when possible to limit computational time and improve readability (this is not just a sofistik thing, but general for all programming)

In this case, since it’s possible to write ... bgrp 1,2,3,4 proj yy... it should also be possible to input it with an array.

does your loop have a noticeable execution time? if not, look for optimization of computing time elsewhere, and if so, I do not know the solution :slight_smile: based on my observation, the list of values as a parameter is turned into a loop anyway.

I finally figured a solution by using secondary groups.

+prog aqua urs:35.1
    head Materials
    MAT 1 E 35000 mue 0.3 gam 25
    SREC 1 H 1000[mm] B 500[mm] MNO 1

END
+prog sofimshc urs:35.2
    head Geometry
    SYST 2D GDIV 200000 GDIR NEGY
    CTRL MESH 1
    UNIT 5

    loop#i 10
        SPT #i+1 X #i*2000[mm] Y 0 fix pp
    endloop


    loop#i 9
        SLN #i+1 NPA #i+1 NPE #i+2 SNO 1 GRP #i+1
    endloop


    GRP NO 'GR1'
        loop#i 9
            SLN #i+1
        endloop

END
+prog sofiload urs:35.3
    head Load
        let#mygrp 1,2,3,4

        LC 1 TYPE 'NONE'
                LINE REF BGRP 'GR1' PROJ YY WIDE 10  P1 10 X1  0 Y1 5[m] $$
                                                            X2 10[m] Y2 5[m]

        LC 2 TYPE 'NONE'
                LINE REF BGRP #mygrp PROJ YY WIDE 10  P1 10 X1  0 Y1 5[m] $$
                                                            X2 10[m] Y2 5[m]

END

Sorry for the late reply, but after finally figuring out how to do the array thing I figured I’d give and update on the performance.

In this small example model it doesn’t change a thing, but in my large model I have the following:

Old code with loop:

loop#e #nelem-1
    AREA REF QGRP NO (100*(#e+1)+1 (#e+1)*100+#ndiv*4 1) Proj ZZ WIDE 500[m] TYPE PZZ P1 #var(0) X1 #var(1) Y1 #var(3) Z1 0  $$
                                                                                                 X2 #var(2) Y2 #var(4) Z2 0
endloop

New code with array

AREA REF QGRP 'Base' Proj ZZ WIDE 500[m] TYPE PZZ P1 #var(0) X1 #var(1) Y1 #var(3) Z1 0 $$
                                                             X2 #var(2) Y2 #var(4) Z2 0

In this project, my execution time drops from 41 sec to 4 sec after moving away from the loop, so there is significant performance increases to be had from dropping the loops!

2 Likes

So the key point is to apply loads to the QGRP using the secondary group ‘Base’ instead of the regular group?

well, yes and no.

It’s shouldn’t be an issue to apply loads using the regular groups, but depending on the group numbering and exactly which groups you wish to apply loads to, it might be difficult to apply it to the correct groups without using loops.

As such, you’ll be better off creating secondary groups prior to the load application and then applying the loads to the secondary groups.

Long story short;
the key point is to stay away from loops :slight_smile:

I guess longer calculation is not caused by loop itself, but due to multiple n_elem-1 time area load definition.
The same could be done with prior choosing groups and then applying load without specyfing a group in area cmd:
grp 1,2,3,4
areq ref qgrp proj zz wide 500…