Skip to content
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

Go through FORTRAN Code to find what each "chunk" does #14

Closed
smiths opened this issue May 4, 2022 · 36 comments
Closed

Go through FORTRAN Code to find what each "chunk" does #14

smiths opened this issue May 4, 2022 · 36 comments
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@smiths
Copy link
Owner

smiths commented May 4, 2022

To create new code, we need to figure out what the old code does. We should go through the FORTRAN CODE and say what each "chunk" of code does. I think we can use the features of GitHub to make this relatively easy to do. For instance, we can do something like:

Code to initialize program, declare variables for PP, G and WC, and open files:

PARAMETER (NL=30,NQ=101)
COMMON/SLA/P(NQ),IE(NQ,1),EO(NL),DX,NBX,NEL,PII,NOUT
DIMENSION PP(NQ),G(NL),WC(NL)
CHARACTER *64 TITLE
OPEN(5,FILE='VDIN.DAT')
OPEN(6,FILE='VDOU.DAT')
READ(5,'(A)') TITLE
WRITE(6,'(1X,A)') TITLE

We should probably also keep a dictionary of variable names and their meaning. For instance, I don't know what PP, G and WC are. 😄 I feel like the W means water. G might be specific gravity? We'll figure it out.

@EmilSoleymani
Copy link
Collaborator

The following code opens input and output file. It reads the first line (the title) and copies it into the output file:

OPEN(5,FILE='VDIN.DAT')
OPEN(6,FILE='VDOU.DAT')
READ(5,'(A)') TITLE
WRITE(6,'(1X,A)') TITLE

The following code reads the second line from the input file. It parses NPROB, NOPT, NBPRES, NNP, NBX, NMAT, DX. It first prints NPROB, NNP, NBX, NMAT, DX. NOPT and NBPRES are used to determine soil type and foundation type. The if statements select what FORMAT string to print from lines 104-114:

READ(5,*) NPROB,NOPT,NBPRES,NNP,NBX,NMAT,DX
WRITE(6,3) NPROB,NNP,NBX,NMAT,DX
IF(NOPT.EQ.0)WRITE(6,4)
IF(NOPT.EQ.1)WRITE(6,5)
IF(NOPT.EQ.2)WRITE(6,6)
IF(NOPT.EQ.3)WRITE(6,7)
IF(NOPT.EQ.4)WRITE(6,8)
IF(NBPRES.EQ.1)WRITE(6,9)
IF(NBPRES.EQ.2)WRITE(6,10)

vdisp/fortran_src/vdisp.for

Lines 104 to 114 in 0ee7174

3 FORMAT (/,1X,'NUMBER OF PROBLEMS=',I5,5X,'NUMBER OF NODAL POINTS='
+,I5,/,1X,'NUMBR OF NODAL POINT AT BOTTOM OF FOUNDATION=',I11,/,1X
+,'NUMBER OF DIFFERENT SOIL LAYERS=',I5,5X,'INCRMENT DEPTH=',F10.2
+,' FT',/)
4 FORMAT(10X,'CONSOLIDATION SWELL MODEL',/)
5 FORMAT(10X,'LEONARDS AND FROST MODEL',/)
6 FORMAT(10X,'SCHMERTMANN MODEL',/)
7 FORMAT(10X,'COLLAPSIBLE SOIL',/)
8 FORMAT(10X,'ELASTIC SOIL',/)
9 FORMAT(10X,'RECTANGULAR SLAB FOUNDATION',/)
10 FORMAT(10X,'LONG CONTINUOUS STRIP FOUNDATION',/)

The following code calculates DEPF and DEPPR and prints them with format strings on lines 115 and 116 :

DEPF=DX*FLOAT(NBX-1)
WRITE(6,11)DEPF
DEPPR = DX*FLOAT(NNP-1)
WRITE(6,12)DEPPR

vdisp/fortran_src/vdisp.for

Lines 115 to 116 in 0ee7174

11 FORMAT(1X,'DEPTH OF FOUNDATION =',12X,F10.2,' FEET')
12 FORMAT(1X,'TOTAL DEPTH OF THE SOIL PROFILE =',F10.2,' FEET')

Here is a dictionary I have come up with so far for these code snippets, based on the format strings:

  • NPROB: Number of problems
  • NOPT = Number of option? Model Number?

    0: Consolidation Swell Model
    1: Leaonards and Frost Model
    2: Schmertmann Model
    3: Collapsible Soil
    4: Elastic Soil

  • NBPRES: B = Base? Number of bases present?

    1: Rectangular Slab Foundation
    2: Long Continuous Strip Foundation

  • NNP: Number of Nodal Points
  • NBX: Number of Nodal Points at Bottom of Foundation
  • NMAT: Number of Different Soil Layers
  • DX: Increment depth (delta x?)
  • DEPF: Depth of Foundation

    DEPF = DX*FLOAT(NBX-1)

  • DEPPR: Total Depth Of Soil Profile

    DEPPR = DX*FLOAT(NNP-1)

Having a hard time following the specifics of this part, however I understand it prints out the first table which is Number of Soil vs. Element. It prints each entry with format 32 on line 118. At the end it prints the header for the next table, which shows the specific gravity, water content and void ratio for each material:

NEL=NNP-1
L=0
WRITE(6,21)
22 READ(5,*)N,IE(N,1)
25 L=L+1
IF(N-L .gt. 0) GOTO 30
35 WRITE(6,32)L,IE(L,1)
IF(NEL-L .gt. 0) GOTO 22
40 CONTINUE
WRITE(6,390)
GOTO 400
30 IE(L,1)=IE(L-1,1)
WRITE(6,32)L,IE(L,1)
GOTO 25
400 READ(5,*) M,G(M),WC(M),EO(M)
401 FORMAT(I5,3F10.3)
IF(NMAT-M .lt. 0) GOTO 403
IF(NMAT-M .eq. 0) GOTO 405
GOTO 400
403 WRITE(6,404) M

Line 32 just writes the header of the table that is about to be printed. My problem in understanding comes from IE(N,1) on line 33. I understand that IE(NQ,1) is defined in a COMMON block on line 2 in order to be accessed in other subroutines, however I don't understand what it is - a function? a variable? what are we passing into it? how are we reading from it if I can't find its definition anywhere in the document? However, I do understand what is happening, just now HOW it's happening. In VDIN.DAT we have:

1 1 

12 2
 
16 2

This is read by the code snippet, and in a table fills in all the intermediate values ( > 1 and < 12 is 1, > 12 and < 16 is 2) like so:

ELEMENT	NUMBER OF SOIL

    1            1
    2            1
    3            1
    4            1
    5            1
    6            1
    7            1
    8            1
    9            1
   10            1
   11            1
   12            2
   13            2
   14            2
   15            2
   16            2

Now after printing this, and the header for the next table ( MATERIAL SPECIFIC GRAVITY WATER CONTENT,% VOID RATIO ), the following code enumerates the materials (number of different soil layers) and lists each ones Specific gravity, water content and void ratio:

405 DO M=1,NMAT
WRITE(6,407) M,G(M),WC(M),EO(M)
ENDDO

Thus, we can deduce the following naming:

  • M: Material
  • G(M): Specific gravity of material M
  • WC(M): Water content of material M
  • EO(M): Void ratio of material M

@EmilSoleymani
Copy link
Collaborator

The following code snippet reads in a bunch of values from VDIN.DAT. It prints out some info depending on the values (specifics listed below):

1000 READ(5,*) DGWT,IOPTION,NOUT
READ(5,*)Q,BLEN,BWID,MRECT
WRITE(6,50) DGWT
IF(NOUT.EQ.1)WRITE(6,51)
IF(NOUT.EQ.0)WRITE(6,52)
IF(IOPTION.EQ.0.OR.NOPT.EQ.1)WRITE(6,61)
IF(IOPTION.EQ.1.AND.NOPT.EQ.0)WRITE(6,62)
WRITE(6,90)Q,BLEN,BWID
IF(MRECT.EQ.0)WRITE(6,91)
IF(MRECT.EQ.1)WRITE(6,92)

  • NOUT: Number of outputs?

    0: Total Displacement Only
    1: Discplacements at Each Depth Output

  • IOPTION: Related to equilibrium

    IOPTION = 1 OR NOPT = 0: Equilibrium Hydrostatic Profile Above Water Table
    IOPTION = 0 OR NOPT = 1: Equilibrium Saturated Profile Above Water Table

  • Q: Applied Pressure on Foundation
  • BLEN: (base?) length
  • BWID: (base?) width
  • MRECT: Center?

    1: Corner of slab or edge of long strip footing
    0: Center of Foundation

@EmilSoleymani
Copy link
Collaborator

EmilSoleymani commented May 5, 2022

The following code calculates effective overburden pressure (According to this link it could also be called effective stress which is what our geotechnical engineering notes call it). There are two arrays, P and PP, which seem to always both have the same value within this block of code (thanks to PP(I)=P(I) on line 77). It seems to loop through all the nodal points (I=2,NNP), retrieving the value from the table we calculated before here, which tell us the material at each nodal point? We use this material's Specific Gravity, G(MTYP), water content, WC(MTYP) (divided by 100 probably for unit conversions - UPDATE: DIVIDE BY 100 SINCE INPUT IS GIVEN AS PERCENT BUT WE NEED IT AS DECIMAL), and void ratio, EO(MTYP) to make the calculations for some value GAMM (Gamma?). There is a constant GAW=0.03125 that I can't figure out the name for that is also used in these calculations. The pressure of each nodal point is the pressure of the previous one + DX*GAMM. Calculations seem similar to what is happening in this Chegg article about calculating effective overburden pressure. Line 81 skips directly to calling of SLAB subroutine if IOPTION=1 or NOPT != 0, else there are a bunch of calculations with variables who's names or purpose I can not currently figure out prior to calling the subroutine:

C CALCULATION OF EFFECTIVE OVERBURDEN PRESSURE
105 P(1)=0.0
PP(1)=0.0
DXX=DX
DO I=2,NNP
MTYP=IE(I-1,1)
WCC=WC(MTYP)/100.
GAMM=G(MTYP)*GAW*(1.+WCC)/(1.+EO(MTYP))
IF(DXX.GT.DGWT)GAMM=GAMM-GAW
P(I)=P(I-1)+DX*GAMM
PP(I)=P(I)
DXX=DXX+DX
ENDDO
IF(NOPT.NE.0.OR.IOPTION.EQ.0)GOTO 120
MO=IFIX(DGWT/DX)
IF(MO.GT.NNP)MO=NNP
DOI=1,MO
BN=DGWT/DX-FLOAT(I-1)
P(I)=P(I)+BN*DX*GAW
ENDDO
120 CALL SLAB(Q,BLEN,BWID,MRECT,NBPRES,PP(NBX))

Note: There is a typo on line 85, it should say DO I=1,MO

@smiths
Copy link
Owner Author

smiths commented May 5, 2022

Great work so far @EmilSoleymani. I have some comments on the parts of your review that I can clarify:

  • I'm sure you have already deduced this, but FORTRAN users use N as a prefix for variables that are natural numbers. In the vdisp.for code the "N" variables are counts of different things. They also use N when they are representing an enumerated type directly via natural number values, like for NOPT.
  • Hopefully, Julia has an enumerated type that we can use, instead of adopting a convention around integer values representing different options.
  • FORTRAN programmers often use 1 and 0 for True and False, respectively. We should use a Boolean to do the same thing.
  • FORTRAN programmers use the prefix I for integers. (This isn't just for I, from the Stanford website: "If a variable is undeclared, Fortran 77 uses a set of implicit rules to establish the type. This means all variables starting with the letters i-n are integers and all others are real.")
  • Yes DX means Delta X
  • IE is an array. It appears to be a 2D array to represent a column vector. The index of IE gives the element number and the value at that index is the soil layer number. The soil is discretized vertically into elements (the soil between two nodal points is an "element" of soil.) Each element is assigned a layer. Each layer is represented by an integer. Each layer has different material properties.
  • You mention not knowing how IE is defined -- you are reading it from the input file. The code from Lines 30 to 49 populates IE based on the information from the input file.
  • NOUT isn't the number of outputs, it is selecting an option for what output will be put in the output file. It really isn't a natural number. It should be represented by an enumerated type
  • The IOPTION and NOPT cases are confusing (equal = 0 or 1 cases). I thought a case was missing, but after I build a truth table, it appears that they covered all cases. We should be able to code and document this better. 😄
  • The prefix B for BLEN and BWID is likely there to implicitly make the type a float. Your interpretation of the B for Base also makes sense.
  • It seems like MRECT is identifying whether the calculation is for the edge of the slab or the centre
  • For the effective overburden pressure calculation, I wonder if you can find an explanation in the settlement book. I don't know if the pdf is searchable, because it was scanned, but if it is, you could search for 0.03125. They should say somewhere what this value means.
  • This exercise is really highlighting the importance of proper requirements. The theory manual (the settlement book) is very long and detailed, but the traceability between the theory and the code is not clear. We will do better. 😄
  • Very interesting that you found a typo in the code! We can use this to motivate our unit testing. My guess is that the typo was never caught because the cases where it is relevant were never tested.

@EmilSoleymani
Copy link
Collaborator

Slab Subroutine

The SLAB subroutine seems to use some of the previously seen data to find the respective surcharge pressure values and store them in the array P.

vdisp/fortran_src/vdisp.for

Lines 221 to 263 in 0ee7174

SUBROUTINE SLAB(Q,BLEN,BWID,MRECT,NBPRES,WT)
PARAMETER (NL=30,NQ=101)
COMMON/SLA/P(NQ),IE(NQ,1),EO(NL),DX,NBX,NEL,PII,NOUT
C
C CALCULATION OF SURCHARGE PRESSURE FROM STRUCTURE
C
NNP=NEL+1
ANBX=FLOAT(NBX)*DX
DXX=0.0
BPRE1=Q-WT
BPRES=BPRE1
DO 100 I=NBX,NNP
IF(DXX.LT.0.01) GOTO 80
MTYP=IE(I-1,1)
IF(NBPRES.EQ.2) GOTO 70
BL=BLEN
BW=BWID
BPR=BPRES
IF(MRECT.EQ.1) GOTO 50
BL=BLEN/2.
BW=BWID/2.
50 VE2=(BL**2.+BW**2.+DXX**2.)/(DXX**2.)
VE=VE2**0.5
AN=BL*BW/(DXX**2.)
AN2=AN**2.
ENM=(2.*AN*VE/(VE2+AN2))*(VE2+1.)/VE2
FNM=2.*AN*VE/(VE2-AN2)
IF(MRECT.EQ.1)BPR=BPRES/4.
AB=ATAN(FNM)
IF(FNM.LT.0.) AB=PII+AB
P(I)=P(I)+BPR*(ENM+AB)/PII
GOTO 90
70 DB=DXX/BWID
PS=-0.157-0.22*DB
IF(MRECT.EQ.0.AND.DB.LT.2.5)PS=-0.28*DB
PS=10.**PS
P(I)=P(I)+BPRES*PS
GOTO 90
80 P(I)=P(I)+BPRES
90 DXX=DXX+DX
100 CONTINUE
RETURN
END

Recall that the variables NBPRES and MRECT help determine the type of foundation and whether the calculation is at the edge of the slab or at the centre.

We can use Julia's @enum macro for NBPRES and a simple Boolean for MRECT.

The code is just a series of calculations. It is hard to understand the meaning of all the intermediate variables used in the calculations, assuming they have one at all, however it will be trivial to replicate the same process.

@smiths
Copy link
Owner Author

smiths commented May 5, 2022

We should try to find the SLAB equations in the settlement book (pdf). I agree that they are hard to deduce from reading the code. We can just translate the code to Julia, but I would like to also figure out what theory this code is based on. We'll need this information for our documentation.

@EmilSoleymani
Copy link
Collaborator

Appendix F on Page 97 of the Settlments Book will be very useful, I was not aware there was an appendix about the code. It has helped me add to our dictionary of variables:

  • NEL: number of elements (one less than the number of nodal points NNP)
  • NL: maximum number of soil layers allowed (30)
  • NQ: maximum number of soil nodal points allowed (101)

We could potentially increase these numbers, original developers were probably constrained by storage

As we have figured out so far, the program assigns a layer number to each soil element. It then calculates the effective overburden pressure which is prior to the placement of the foundation. The subroutine SLAB calculates the change in effective vertical pressures in the soil after the placement of the foundation. It does so using the Boussinesq pressure distribution. Based off the use of ATAN in the SLAB subroutine, the formula used is one of the following scenarios (found from Table-C1 beginning on page 81):
image
image
Infact, the settlement book shows the original FORTRAN code, in which the author provides the dictionary I have been building through comments, along with specification of the input:
image
image

The remaining five subroutines are explained in the appendix as well and I will be looking over those next. Only one of them gets called depending on NOPT.

@smiths
Copy link
Owner Author

smiths commented May 5, 2022

Yes, this is very valuable information. I'm glad to see that our guesses were on the right track, but this is a quicker way to understand the code.

@EmilSoleymani
Copy link
Collaborator

Subroutine MECH

Calculates heave or consolidation from result of one-dimensional consolidometer swell tests performed on cohesive soil for each layer in soil profile. After examining the settlement book and geotechnical engineering notes, I seem to have matched lines 159-165 to some formulas/theory!

vdisp/fortran_src/vdisp.for

Lines 159 to 165 in 0ee7174

MTYP=IE(I,1)
PR=(P(I)+P(I+1))/2.
CA=SP(MTYP)/PR
CB=SP(MTYP)/PM(MTYP)
CBB=PM(MTYP)/PR
E=EO(MTYP)+CS(MTYP)*ALOG10(CA)
IF(PR.GT.PM(MTYP)) E=EO(MTYP)+CS(MTYP)*ALOG10(CB)+CC(MTYP)*ALOG10

Examining line 164, we see a calculation for final void ratio. This calculation includes taking log_10 of a variable called CA. Examining line 161 indicates that CA is the ratio of two swell pressures.
image
This matches formula (3-21) on page 28 of the settlements book perfectly. In the picture they are finding change in void ratio, but changing that to (final void ratio - initial void ratio) and moving the initial to RHS produces the calculations on line 164 exactly

Examining line 165, we see that if PR > PM(MTYP) we do a similar calculation with an extra log term. This can be matched to equation (3-23) on page 30 of the settlements book:
image
The inequality on the lines below the equation explain the IF statement in the FORTRAN code. We can now deduce the following:

  • SP(MTYP) = sigma_fj prime = swell pressure of soil layer M
  • PR = sigma_oj prime = P(I)+P(I+1)/2
  • PM(MTYP) = sigma_pi prime = max past pressure

Note: Code has order of log terms switched around, which caused great confusion for me at first. Noticing this tiny detail clears things up.
Note 2: is there a nicer way for me to write greek letters and subscripts in markdown?

@EmilSoleymani
Copy link
Collaborator

Subroutine Mech (continued)

On page 30 of the settlements textbook, there is a step-by-step algorithm outlining the procedure of primary consolidation calucation:
image
In the previous comment ( lines 159-165 ) we performed the calculations for Step 6 of this procedure. Examining the lines that come right after, lines 167-173, we see a similar structure to the formula in Step 7:

vdisp/fortran_src/vdisp.for

Lines 167 to 173 in 0ee7174

DEL=(E-EO(MTYP))/(1.+EO(MTYP))
IF(NOUT.EQ.0) GOTO 36
DELP=SP(MTYP)-PR
WRITE(6,110) I,DXX,DEL,DELP
36 DELH1=DELH1+DX*DEL
DXX=DXX+DX
40 CONTINUE

The equation is equation (3-20) on page 28 of the settlement analysis book:
image
Note that the numerator here is what we calculate in Step 6 which was covered in the previous comment.

It seems Step 7, which is just summing up all the individual settlements, is incorporated into the code by just adding current DEL to DELH1, thus. accumulating all settlements into DELH1. Lines 174-194 seem to be a repeat of the same procedure with a different variable DELH2, just with a different DXX value. This code seems to execute when NOUT=0. Regardless, DELH2 is added is added onto DELH1. From my understanding, since NOUT=0 means we only output heave computations, DELH2 is the result of heave computations. Following that logic, since NOUT=1 means we have heave computations AND pressure at each depth increment, DELH1 stores the value of sum of pressures at each depth after execution of lines 159-173 as discussed previously, then when DELH2 is added to it it stores the final value that the user wants.

@EmilSoleymani
Copy link
Collaborator

While reading about the LEON subroutine and its (many) resulting formulas, I think I might have stumbled upon what the constant GAW is on page 4 of the settlements textbook:
image
This makes sense since gamma_w could be abbreviated to GAW. The textbook gives a version accurate to 3 decimal places, while the code uses the slightly more accurate 0.03125.

@smiths
Copy link
Owner Author

smiths commented May 6, 2022

@EmilSoleymani, I'm sure you are right about GAW being the specific weight of water. However, the 0.031 tsf(?) is weird. The specific weight of water is around 9.807 kN/m^3 in SI. I thought that tsf might be the imperial equivalent, but my google search suggests that tsf is tonnes per square foot. tsf is a pressure unit. It applies to an area, while specific weight applies to a volume. I'm not sure how to rationalize this. Your text is cut off though. Is there something after tsf that could be a clue?

@smiths
Copy link
Owner Author

smiths commented May 6, 2022

Your work on deducing the meaning of the code fragments looks great. This will take some iteration, but you are making great progress.

With respect to your question about math in GitHub markdown, I googled it. There appears to be a hack that works. Here is an example:

If you need them for some reason, here is a list of GitHub markdown emoji markup:

https://gist.github.com/rxaviers/7360908

@EmilSoleymani
Copy link
Collaborator

Subroutine Leon

Subroutine Leon calculates immediate settlement of shallow foundations on granular soils (Leonard's and Frost Model). It's formula can be found on page 97:
image
The book gives a complicated breakdown of each variable and I had to go all over the book looking for intermediate formulas. I took notes on everything I found and they are available for download in the following pdf:
Leonard’s and Frost Model.pdf
I will now be comparing the code to my findings in my notes. First of all, the delta p is referred to as QNET in the code. It is calculated and printed in lines 297-299 of the code:

vdisp/fortran_src/vdisp.for

Lines 297 to 299 in 0ee7174

QNET=Q-PP(NBX)
WRITE(6,17)QNET
17 FORMAT(/,1X,'QNET=',F10.5)

Constant c1 is calculated on lines 301-302. The formula matches perfectly with my notes, and as stated in book this constant must be greater than 0.5 thus it is adjusted if needed on line 302.

vdisp/fortran_src/vdisp.for

Lines 301 to 302 in 0ee7174

C1=1 - 0.5*PP(NBX)/QNET
IF(C1.LT.0.5) C1=0.5

UW is calculated in the textbook by multiplying z_w and gamma_w (GAW), and that is shown exactly in the code.
image
IF(DXX.GT.DGWT) UW=(DXX-DGWT)*GAW

The value of K_d, the horizontal stress index, is calculated on line 311 as the variable AKD. Its formula matches my notes.
AKD = (PO(MTYP)-UW)/PR1

I am not sure what is being calculated on line 312. I have searched all over the book for the calculation (P_1 - P_0)/(P_0 -u_w) with no success. It might be the result of dividing two formulas by each other. I will keep looking for this variables meaning. The next line calculates the value of E_D just as expected:
ED = 34.7*(P1(MTYP)-PO(MTYP))

The next line calculates q_c/(sigma_v prime) which is part of the last term of calculating the coefficient of earth pressure, K_oc.
RQC = QC(MTYP)/PR1

The next line calculates the coefficient of earth pressure and calls it AK0, with the exact formula as in my notes:
AKO=0.376+0.095*AKD-0.0017*RQC

Lines 316-322 deal with calculating constant phi_ps, the plane strain angle, which as in my notes is calculated using the BICUBE subroutine. At the moment I have no clue what is going on in that subroutine and the book provides no help with regards to this, so I will be treating this as a blackbox for now that just outputs us phi_ps. Line 322 converts PHIPS from degrees to radians.

vdisp/fortran_src/vdisp.for

Lines 316 to 322 in 0ee7174

EC = AKO
S3 = RQC
MM=0
UC=0.0
CALL BICUBE(UC,EC,S3)
S3=RQC
PHIPS=UC*PII/180.

Lines 323-333 deal with calculating phi_ax, the axial friction angle, from phi_s. Once again, the textbook makes no effort in explaining this. They give a formula which is in my notes that is completely different to what is going on in the code. Nevertheless, the correct value of phi_ax is stored in variable PHIAX, then converted to radians and stored in PHI in line 333.

vdisp/fortran_src/vdisp.for

Lines 323 to 333 in 0ee7174

AKA = (1-SIN(PHIPS))/(1+SIN(PHIPS))
AKP = (1+SIN(PHIPS))/(1-SIN(PHIPS))
AAK = AKO
IF(AKO.LE.AKA)AAK=AKA
IF(AKO.GE.AKP)AAK=AKP
IF(ABS(AAK-AKO).GT.0.01)EC=AAK
IF(ABS(AAK-AKO).GT.0.01) CALL BICUBE(UC,EC,S3)
S3=RQC
PHIAX=UC
IF(UC.GT.32.0) PHIAX=UC-((UC-32.)/3.)
PHI=PHIAX*PII/180.

Line 334 calculates the over consolidation ratio, OCR, with the same formula I have in my notes:
OCR=(AAK/(1-SIN(PHI)))**(1./(0.8*SIN(PHI)))

The next line calculates sigma_p prime, the preconsolidation/max past pressure, by multiiplying OCR and sigma_v prime.
PM=OCR*PR1

Lines 336-337 calculate R_izoc, the ratio of stress increment of overconsolidated soil in layer to total stress increment in layer. Formula is same as in my notes. Value stored in variable ROC. It is adjusted to 0 if it was negative.

vdisp/fortran_src/vdisp.for

Lines 336 to 337 in 0ee7174

ROC=(PM-PR1)/(PR-PR1)
IF(ROC.LT.0.0)ROC=0.0

Lines 338-339 calculate R_iznc, the ratio of stress increment of normally consolidated soil in layer to total stress increment in layer. Formula is same as in my notes. Value stored in variable RNC. It is adjusted to 0 if it was negative.

vdisp/fortran_src/vdisp.for

Lines 338 to 339 in 0ee7174

RNC=(PR-PM)/(PR-PR1)
IF(RNC.LT.0.0)RNC=0.0

@EmilSoleymani
Copy link
Collaborator

image
image
Here are the paragraphs on page 4 of the settlements textbook which refer to the unit weight of water with the units tsf. I too was confused upon reading this.

@smiths
Copy link
Owner Author

smiths commented May 6, 2022

Great analysis @EmilSoleymani. I'm not surprised there are things that are not yet clear. There is a lot going on in this code. We will be able to ask Dr. Stolle questions too. The variables with K in them, like AKD, may be related to the bulk modulus. The A is probably just there as a prefix to show the variable is a float.

@smiths
Copy link
Owner Author

smiths commented May 6, 2022

I wonder if the units of tsf work with gamma because they are talking about a unit width of soil. Gamma is in N/m^3 in general, but for a unit width of soil, it is in N/m^2.

We should be careful with the units. We'll want the code to also work for SI units.

@EmilSoleymani
Copy link
Collaborator

Subroutine Leon (continued)

Last time I stated that the phi_ax calculation was not matching the formula in my notes, however it actually was (almost). Lines 331-333 seem to be making the phi_ax calculation based on the formula in my notes where the value of phi_ps is stored in variable UC. There might be a typo in the textbook formula since it clearly says phi_ax = phi_px - [ (phi_ps - 32) / 3] while the calculations treat phi_px as phi_ps. This wouldn't be the first time I've noticed an error in the subscript of formulas in the textbook (looking at the picture for the main formula in my previous post about this subroutine, the constant C_1 is labeled as C_i? In the K_0 calculations in the book, K_D was written as K_p but explained as K_D?)
image

vdisp/fortran_src/vdisp.for

Lines 331 to 333 in 0ee7174

PHIAX=UC
IF(UC.GT.32.0) PHIAX=UC-((UC-32.)/3.)
PHI=PHIAX*PII/180.

Note: I just found an online version of the book here that had the correct phi_ax formula:
image
Note: From another book I found out why there was a conversion from degrees to radians. The formula labelled as (F-4) above uses degrees in its calculations. This will be important for us when we reproduce this code so we don't perform conversions in the wrong steps:
image
Lines 343-348 deal with the calculation of the influence factor, I_zp, which is better explained in the Schmertmann model (from my understanding, Leon and Frosts model is a slight improvement upon the Schmertman model - they share many similarities):
image

vdisp/fortran_src/vdisp.for

Lines 343 to 348 in 0ee7174

SIGM=PR1
AIZP=0.5+0.1*(QNET/SIGM)**0.5
DEPT=DXX-FLOAT(NBX-1)*DX
AIZ=0.1+(AIZP-0.1)*DEPT/(0.5*BWID)
IF(DEPT.GT.0.5*BWID)AIZ=AIZP+AIZP/3.0-AIZP*DEPT/(1.5*BWID)
IF(DEPT.GT.2*BWID)AIZ=0.0

Lines 350-357 are a repeat of 341-349, but with some slight differences. The variable NBPRES decides which of the two blocks executes:

vdisp/fortran_src/vdisp.for

Lines 340 to 357 in 0ee7174

IF(NBPRES.EQ.2) GOTO 100
ANN=0.5*BWID/DX + DX*FLOAT(NBX-1)
NN=IFIX(ANN)
SIGM=PR1
AIZP=0.5+0.1*(QNET/SIGM)**0.5
DEPT=DXX-FLOAT(NBX-1)*DX
AIZ=0.1+(AIZP-0.1)*DEPT/(0.5*BWID)
IF(DEPT.GT.0.5*BWID)AIZ=AIZP+AIZP/3.0-AIZP*DEPT/(1.5*BWID)
IF(DEPT.GT.2*BWID)AIZ=0.0
GOTO 200
100 ANN=BWID/DX + DX*FLOAT(NBX-1)
NN=IFIX(ANN)
SIGM=PR1
AIZP=0.5+0.1*(QNET/SIGM)**0.5
DEPT=DXX-FLOAT(NBX-1)*DX
AIZ=0.2+(AIZP-0.2)*DEPT/BWID
IF(DEPT.GT.BWID)AIZ=AIZP+AIZP/3.-AIZP*DEPT/(3.*BWID)
IF(DEPT.GT.4*BWID)AIZ=0.0

There seems to be another typo in the settlements book, this time relating to the elastic soil moduli, E_izoc and E_iznc. They are both equal to some constant times E_D, while the book writes E_p:
image
Those formulas, paired with the following special case give us the calculations for the elastic soil moduli which are reflected in lines 358-360 of the code:
image

vdisp/fortran_src/vdisp.for

Lines 358 to 360 in 0ee7174

200 F=0.7
IF(ROC.LE.0.0)F=0.9
DEL=-C1*QNET*AIZ*DX*(ROC/(3.5*ED)+RNC/(F*ED))

As seen above, line 360 does the final calculation which is added onto variable DELH, which is the value this subroutine writes to the output file.

@smiths
Copy link
Owner Author

smiths commented May 9, 2022

This is a great review of the code and the settlement book. I know it is frustrating when the book and the code don't agree. This is the motivation for having one source for the documentation and the code, as done in literate programming and even more dramatically with Drasil.

The examples where the documentation and the code disagree, or where there are mistakes in the documentation, will be very valuable for future papers. I'm going to create an issue for us to keep track of those.

@EmilSoleymani
Copy link
Collaborator

Subroutine Schmert

Subroutine Schmert calculates immediate settlement of shallow foundations on granular soils (Schmertmann model). As mentioned in subroutine Leon explanation, the Leonards and Frost model is very similar to the Schmertmann model. Consequently, most of the calculations remain the same with some slight differences being present. The formula of the Schmertmann model is as follows, found on p.104 of the settlments textbook:
image
Note: This subroutine is much simpler than the LEON subroutine. The calculations for R_izoc and R_iznc (and all their subsequent formulas like OCR, phi_ax, phi_ps) were the reason for many lines of code. Since these variables don't exist, the remaining calculations are quite simple.

The first big difference of this model is the presence of a new constant, C_t. This is the correction for time-dependant increase in settlement. C_t can be found by the following formula where t is the time in years following construction when settlement is to be calculated for:
image
The second difference is the calculation of the soil modulus, E_si:
image
An interesting point here is that when NOPT=2 we call SCHMERT and expect to read q_c data from the input file, but when NOPT=4, E_si data for each layer of soil is passed in directly (useful for when q_c data is not availabl, but E_si can be determined through tests).
Lines 623-628 are same as in the LEON subroutine - they initialize some variables and calculate delta_p in variable QNET. Then the constant c_1 is calculated and stored in variable C1, which will have a value no less than 0.5:

vdisp/fortran_src/vdisp.for

Lines 623 to 628 in 0ee7174

DELH=0.0
DEL=0.0
QNET=Q-PP(NBX)
DXX=DX*FLOAT(NBX) - DX/2.
C1=1 - 0.5*PP(NBX)/QNET
IF(C1.LT.0.5) C1=0.5

Lines 629 and 630 calculate constant C_t based on formula given above:

vdisp/fortran_src/vdisp.for

Lines 629 to 630 in 0ee7174

FF=TIME/0.1
CT=1+0.2*ALOG10(FF)

Lines 636-638 calculate E_si as described in textbook:

vdisp/fortran_src/vdisp.for

Lines 636 to 638 in 0ee7174

ESI=QC(MTYP)
IF(NBPRES.EQ.1.AND.JOPT.EQ.2)ESI=2.5*QC(MTYP)
IF(NBPRES.EQ.2.AND.JOPT.EQ.2)ESI=3.5*QC(MTYP)

Lines 639-656 calculate the influence factor, I_zp:

vdisp/fortran_src/vdisp.for

Lines 639 to 656 in 0ee7174

IF(NBPRES.EQ.2) GOTO 100
ANN=0.5*BWID/DX + DX*FLOAT(NBX-1)
NN=IFIX(ANN)
SIGM=PR1
AIZP=0.5+0.1*(QNET/SIGM)**0.5
DEPT=DXX-FLOAT(NBX-1)*DX
AIZ=0.1+(AIZP-0.1)*DEPT/(0.5*BWID)
IF(DEPT.GT.0.5*BWID)AIZ=AIZP+AIZP/3.0-AIZP*DEPT/(1.5*BWID)
IF(DEPT.GT.2*BWID)AIZ=0.0
GOTO 200
100 ANN=BWID/DX + DX*FLOAT(NBX-1)
NN=IFIX(ANN)
SIGM=PR1
AIZP=0.5+0.1*(QNET/SIGM)**0.5
DEPT=DXX-FLOAT(NBX-1)*DX
AIZ=0.2+(AIZP-0.2)*DEPT/BWID
IF(DEPT.GT.BWID)AIZ=AIZP+AIZP/3.-AIZP*DEPT/(3.*BWID)
IF(DEPT.GT.4*BWID)AIZ=0.0

Finally, lines 657-658 put it all together, calculating the final value of the formula which is what is written to the output file:

vdisp/fortran_src/vdisp.for

Lines 657 to 658 in 0ee7174

200 DEL=-C1*CT*QNET*AIZ*DX/ESI
DELH=DELH+DEL

@smiths
Copy link
Owner Author

smiths commented May 9, 2022

Another great summary @EmilSoleymani.

@EmilSoleymani
Copy link
Collaborator

Just to help me remember what I have left to do:

  • Find equations/theory for SLAB subroutine
  • Subroutine COLL
  • Understand subroutine BICUBE
  • Understand subroutine SOLV
  • Understand subroutine SPLINE
  • Deduce purpose of BLOCK DATA (Lines 377-397)

@EmilSoleymani
Copy link
Collaborator

Update:

In subroutine LEON, I previously had no idea where the calculations for variables AKA and AKP came from on lines 323 and 324. I found their formulas in the Geotechnical Engineering notes:

vdisp/fortran_src/vdisp.for

Lines 323 to 324 in 0ee7174

AKA = (1-SIN(PHIPS))/(1+SIN(PHIPS))
AKP = (1+SIN(PHIPS))/(1-SIN(PHIPS))

image
image
Still not sure why they are used. They seem to be used as some sort of "bounds". When the calculated K_o value is less than K_a or greater than K_p, it is adjusted back to within bounds. It seems when the changes exceed a difference of 0.01, we redo the calculations by calling the BICUBE subroutine:

vdisp/fortran_src/vdisp.for

Lines 323 to 329 in 0ee7174

AKA = (1-SIN(PHIPS))/(1+SIN(PHIPS))
AKP = (1+SIN(PHIPS))/(1-SIN(PHIPS))
AAK = AKO
IF(AKO.LE.AKA)AAK=AKA
IF(AKO.GE.AKP)AAK=AKP
IF(ABS(AAK-AKO).GT.0.01)EC=AAK
IF(ABS(AAK-AKO).GT.0.01) CALL BICUBE(UC,EC,S3)

@smiths
Copy link
Owner Author

smiths commented May 9, 2022

Your explanation (about bounds) sounds reasonable @EmilSoleymani. Once we have a set of questions along these lines, we can talk to Dr. Stolle about them.

@EmilSoleymani
Copy link
Collaborator

Block Data

In order to figure out what is going on in the BLOCK DATA code chunk, I wrote a quick script which replicated the initialization of XX, YY, and U arrays and wrote their outputs to console:

      PROGRAM DATATEST
      REAL XX(100), YY(100), U(100)
      DATA (XX(I),I=1,99,11)/9*10./,(XX(I),I=2,99,11)/9*20./,(XX(I),I=3,
     199,11)/9*30./,(XX(I),I=4,99,11)/9*50./,(XX(I),I=5,99,11)/9*100./,
     2(XX(I),I=6,99,11)/9*200./,(XX(I),I=7,99,11)/9*300./,(XX(I),I=8,99,
     311)/9*500./,(XX(I),I=9,99,11)/9*1000./,(XX(I),I=10,99,11)/9*2000./
     4,(XX(I),I=11,99,11)/9*3000./
      DATA (YY(I),I=1,11)/11*0.16/,(YY(I),I=12,22)/11*0.20/,(YY(I),I=23,
     133)/11*0.4/,(YY(I),I=34,44)/11*0.6/,(YY(I),I=45,55)/11*0.8/,(YY(I)
     2,I=56,66)/11*1.0/,(YY(I),I=67,77)/11*2.0/,(YY(I),I=78,88)/11*4./,
     3(YY(I),I=89,99)/11*6./
      DATA (U(I),I=1,99)/25.,30.1,33.2,36.4,39.9,42.8,44.4,46.,48.5,50.5
     1,52.,24.8,30.,33.,36.2,39.7,42.6,44.2,45.8,48.2,50.2,51.5,24.5,29.7
     2,32.6,35.6,39.3,42.1,43.7,45.4,47.5,49.7,51.,24.2,29.5,32.2,35.1
     3,38.8,41.7,43.3,45.,47.2,49.,50.,24.,29.2,31.7,34.7,38.4,41.4,42.9
     4,44.6,46.8,48.6,49.7,23.8,28.8,31.5,34.4,38.,41.,42.5,44.3,46.5,48.
     5 4,49.5,23.,27.5,30.,33.,36.6,39.6,41.2,43.,45.4,47.2,48.4,22.,26.
     6,28.3,31.2,34.5,37.7,39.7,41.5,43.7,45.7,47.,21.,25.,27.2,30.,33.8
     7,36.,38.2,40.3,42.7,44.8,46.1/

      WRITE (*,*) "Testing Block Data from VDispl.for"
     
      WRITE (*,*) "Printing values in XX:"
      DO I=1,99
      WRITE (*,10) I, ": ", XX(I)
   10 FORMAT(I4, A, F8.1)
      END DO

      WRITE (*,*) "Printing values in YY:"
      DO I=1,99
      WRITE (*,20) I, ": ", YY(I)
   20 FORMAT(I4, A, F8.3)
      END DO

      WRITE (*,*) "Printing values in U:"
      DO I=1,99
      WRITE (*,30) I, ": ", U(I)
   30 FORMAT(I4, A, F8.3)
      END DO

      END PROGRAM DATATEST

Output:

 Testing Block Data from VDispl.for
 Printing values in XX:
   1:     10.0
   2:     20.0
   3:     30.0
   4:     50.0
   5:    100.0
   6:    200.0
   7:    300.0
   8:    500.0
   9:   1000.0
  10:   2000.0
  11:   3000.0
  12:     10.0
  13:     20.0
  14:     30.0
  15:     50.0
  16:    100.0
  17:    200.0
  18:    300.0
  19:    500.0
  20:   1000.0
  21:   2000.0
  22:   3000.0
  23:     10.0
  24:     20.0
  25:     30.0
  26:     50.0
  27:    100.0
  28:    200.0
  29:    300.0
  30:    500.0
  31:   1000.0
  32:   2000.0
  33:   3000.0
  34:     10.0
  35:     20.0
  36:     30.0
  37:     50.0
  38:    100.0
  39:    200.0
  40:    300.0
  41:    500.0
  42:   1000.0
  43:   2000.0
  44:   3000.0
  45:     10.0
  46:     20.0
  47:     30.0
  48:     50.0
  49:    100.0
  50:    200.0
  51:    300.0
  52:    500.0
  53:   1000.0
  54:   2000.0
  55:   3000.0
  56:     10.0
  57:     20.0
  58:     30.0
  59:     50.0
  60:    100.0
  61:    200.0
  62:    300.0
  63:    500.0
  64:   1000.0
  65:   2000.0
  66:   3000.0
  67:     10.0
  68:     20.0
  69:     30.0
  70:     50.0
  71:    100.0
  72:    200.0
  73:    300.0
  74:    500.0
  75:   1000.0
  76:   2000.0
  77:   3000.0
  78:     10.0
  79:     20.0
  80:     30.0
  81:     50.0
  82:    100.0
  83:    200.0
  84:    300.0
  85:    500.0
  86:   1000.0
  87:   2000.0
  88:   3000.0
  89:     10.0
  90:     20.0
  91:     30.0
  92:     50.0
  93:    100.0
  94:    200.0
  95:    300.0
  96:    500.0
  97:   1000.0
  98:   2000.0
  99:   3000.0
 Printing values in YY:
   1:    0.160
   2:    0.160
   3:    0.160
   4:    0.160
   5:    0.160
   6:    0.160
   7:    0.160
   8:    0.160
   9:    0.160
  10:    0.160
  11:    0.160
  12:    0.200
  13:    0.200
  14:    0.200
  15:    0.200
  16:    0.200
  17:    0.200
  18:    0.200
  19:    0.200
  20:    0.200
  21:    0.200
  22:    0.200
  23:    0.400
  24:    0.400
  25:    0.400
  26:    0.400
  27:    0.400
  28:    0.400
  29:    0.400
  30:    0.400
  31:    0.400
  32:    0.400
  33:    0.400
  34:    0.600
  35:    0.600
  36:    0.600
  37:    0.600
  38:    0.600
  39:    0.600
  40:    0.600
  41:    0.600
  42:    0.600
  43:    0.600
  44:    0.600
  45:    0.800
  46:    0.800
  47:    0.800
  48:    0.800
  49:    0.800
  50:    0.800
  51:    0.800
  52:    0.800
  53:    0.800
  54:    0.800
  55:    0.800
  56:    1.000
  57:    1.000
  58:    1.000
  59:    1.000
  60:    1.000
  61:    1.000
  62:    1.000
  63:    1.000
  64:    1.000
  65:    1.000
  66:    1.000
  67:    2.000
  68:    2.000
  69:    2.000
  70:    2.000
  71:    2.000
  72:    2.000
  73:    2.000
  74:    2.000
  75:    2.000
  76:    2.000
  77:    2.000
  78:    4.000
  79:    4.000
  80:    4.000
  81:    4.000
  82:    4.000
  83:    4.000
  84:    4.000
  85:    4.000
  86:    4.000
  87:    4.000
  88:    4.000
  89:    6.000
  90:    6.000
  91:    6.000
  92:    6.000
  93:    6.000
  94:    6.000
  95:    6.000
  96:    6.000
  97:    6.000
  98:    6.000
  99:    6.000
 Printing values in U:
   1:   25.000
   2:   30.100
   3:   33.200
   4:   36.400
   5:   39.900
   6:   42.800
   7:   44.400
   8:   46.000
   9:   48.500
  10:   50.500
  11:   52.000
  12:   24.800
  13:   30.000
  14:   33.000
  15:   36.200
  16:   39.700
  17:   42.600
  18:   44.200
  19:   45.800
  20:   48.200
  21:   50.200
  22:   51.500
  23:   24.500
  24:   29.000
  25:   32.600
  26:   35.600
  27:   39.300
  28:   42.100
  29:   43.700
  30:   45.400
  31:   47.500
  32:   49.700
  33:   51.000
  34:   24.200
  35:   29.500
  36:   32.200
  37:   35.100
  38:   38.800
  39:   41.700
  40:   43.300
  41:   45.000
  42:   47.200
  43:   49.000
  44:   50.000
  45:   24.000
  46:   29.200
  47:   31.700
  48:   34.700
  49:   38.400
  50:   41.400
  51:   42.900
  52:   44.600
  53:   46.800
  54:   48.600
  55:   49.700
  56:   23.800
  57:   28.800
  58:   31.500
  59:   34.400
  60:   38.000
  61:   41.000
  62:   42.500
  63:   44.300
  64:   46.500
  65:  484.000
  66:   49.500
  67:   23.000
  68:   27.500
  69:   30.000
  70:   33.000
  71:   36.600
  72:   39.600
  73:   41.200
  74:   43.000
  75:   45.400
  76:   47.200
  77:   48.400
  78:   22.000
  79:   26.000
  80:   28.300
  81:   31.200
  82:   34.500
  83:   37.700
  84:   39.700
  85:   41.500
  86:   43.700
  87:   45.700
  88:   47.000
  89:   21.000
  90:   25.000
  91:   27.200
  92:   30.000
  93:   33.800
  94:   36.000
  95:   38.200
  96:   40.300
  97:   42.700
  98:   44.800
  99:   46.100

At the moment I have no idea where these values are coming from. In the first array, XX, all indices i congruent modulo 11 seem to have the same value but I am not sure where the values 10,20,30,50,100,200,300,500,1000,2000,3000 come from. The other two arrays seem ever more random.

@smiths
Copy link
Owner Author

smiths commented May 10, 2022

Good idea to print out the values @EmilSoleymani. It looks to me like the XX and YY values form a grid in 2D space. I'm guessing that it is a grid underneath the footing. I'm assuming that the x direction is horizontal and the y direction is vertical. The numbers in the x direction are close to the centre of the footing to start with, but then a good distance away at the end. I'm guessing u is the pore water pressure? I would think that this would be something that would be read in for each problem, but maybe it is hard-coded for some reason. Maybe u is something else? I'm fairly sure that u varies over the x-y grid though.

@EmilSoleymani
Copy link
Collaborator

Subroutine BICUBE Data

Similarly, the BICUBE subroutine has long hardcoded data. There is a 100x4 array of ints called KE. I replicated its initialization and checked what the values are. This array is accessed on lines 556-559 through a DO loop:

vdisp/fortran_src/vdisp.for

Lines 556 to 559 in 0ee7174

I=KE(M,1)
J=KE(M,2)
K=KE(M,3)
L=KE(M,4)

To make things even harder to wrap your head around, these variables are used to access the XX and YY arrays seen before:

vdisp/fortran_src/vdisp.for

Lines 565 to 568 in 0ee7174

AA=XX(J)-XX(I)
BB=YY(L)-YY(I)
S3N=S3-XX(I)
ECN=EC-YY(I)

Here is what the KE array looks like:

 Testing BICUBE Data Blocks
   M | I | J | K | L
   -----------------
   1   1   2  13  12
   2   2   3  14  13
   3   3   4  15  14
   4   4   5  16  15
   5   5   6  17  16
   6   6   7  18  17
   7   7   8  19  18
   8   8   9  20  19
   9   9  10  21  20
  10  10  11  22  21
  11  12  13  24  23
  12  13  14  25  24
  13  14  15  26  25
  14  15  16  27  26
  15  16  17  28  27
  16  17  18  29  28
  17  18  19  30  29
  18  19  20  31  30
  19  20  21  32  31
  20  21  22  33  32
  21  23  24  35  34
  22  24  25  36  35
  23  25  26  37  36
  24  26  27  38  37
  25  27  28  39  38
  26  28  29  40  39
  27  29  30  41  40
  28  30  31  42  41
  29  31  32  43  42
  30  32  33  44  43
  31  34  35  46  45
  32  35  36  47  46
  33  36  37  48  47
  34  37  38  49  48
  35  38  39  50  49
  36  39  40  51  50
  37  40  41  52  51
  38  41  42  53  52
  39  42  43  54  53
  40  43  44  55  54
  41  45  46  57  56
  42  46  47  58  57
  43  47  48  59  58
  44  48  49  60  59
  45  49  50  61  60
  46  50  51  62  61
  47  51  52  63  62
  48  52  53  64  63
  49  53  54  65  64
  50  54  55  66  65
  51  56  57  68  67
  52  57  58  69  68
  53  58  59  70  69
  54  59  60  71  70
  55  60  61  72  71
  56  61  62  73  72
  57  62  63  74  73
  58  63  64  75  74
  59  64  65  76  75
  60  65  66  77  76
  61  67  68  79  78
  62  68  69  80  79
  63  69  70  81  80
  64  70  71  82  81
  65  71  72  83  82
  66  72  73  84  83
  67  73  74  85  84
  68  74  75  86  85
  69  75  76  87  86
  70  76  77  88  87
  71  78  79  90  89
  72  79  80  91  90
  73  80  81  92  91
  74  81  82  93  92
  75  82  83  94  93
  76  83  84  95  94
  77  84  85  96  95
  78  85  86  97  96
  79  86  87  98  97
  80  87  88  99  98

There seems to be a pattern where every 11th number is skipped. Each column just starts at a different point. What is the significance of the number 11? XX has same values every 11 numbers, YY has the same values for each group of 11 numbers, and now KE entries are skipping each 11th number

@smiths
Copy link
Owner Author

smiths commented May 10, 2022

I'm fairly sure that the data blocks represent a sequence of square regions/elements. The first number (M) is the element number, the next 4 numbers are the connectivity of its vertices (nodes), as shown in this figure.

ElementConnectivity

Element 1 is made up of nodes 1, 2, 13, 12. Element 2 is made up of nodes 2, 3, 14, 13, etc.

@EmilSoleymani
Copy link
Collaborator

That makes sense! Thus lines 565 and 566 are calculating the length/width of one of these squares assuming XX and YY are their coordinates in 2D space:

vdisp/fortran_src/vdisp.for

Lines 565 to 566 in 0ee7174

AA=XX(J)-XX(I)
BB=YY(L)-YY(I)

@EmilSoleymani
Copy link
Collaborator

Having began the code for calculating effective stresses, I have matched another equation to the theory:

GAMM=G(MTYP)*GAW*(1.+WCC)/(1.+EO(MTYP))

image

The process follows exactly what Dr. Stolle presented to us:

image

You can see the code subtracts GAW from GAMM once the depth is past the depth of the ground water table:

IF(DXX.GT.DGWT)GAMM=GAMM-GAW

This matches the slide, where effective stress = (gamma_sat - gamma_w)z

@smiths
Copy link
Owner Author

smiths commented Jun 3, 2022

Great analysis @EmilSoleymani. At some point we should document the effective stress concept in our SRS. This will definitely be part of our SRS.

We can talk about it more as the summer goes along, but I think the best approach for building the SRS will be to focus on the theoretical models first. We shouldn't try to classify them, just dump likely equations into the document. We can then start to organize as we move forward.

@EmilSoleymani
Copy link
Collaborator

The following lines seem to make an adjustment to the effective stress calculation:

IF(NOPT.NE.0.OR.IOPTION.EQ.0)GOTO 120
MO=IFIX(DGWT/DX)
IF(MO.GT.NNP)MO=NNP
DOI=1,MO
BN=DGWT/DX-FLOAT(I-1)
P(I)=P(I)+BN*DX*GAW
ENDDO

These adjustments follow method 1 from Figure 5-1 on p.99 of the Settlements Analysis book.

image

In our code, the if statement NOPT.NE.0.OR.IOPTION.EQ.0 becomes model != ConsolidationSwell || !equilibriumMoistureProfile. So in this case it appears we add gamma_w * (z - z_a) to each entry, P(i). I think line 86, DGWT/DX - FLOAT(I-1) is performing the (z - z_a) calculation, and line 87 is altering the P array.

Note: The textbook correctly gives gamma_w units of ton/ft^3 here!

@smiths
Copy link
Owner Author

smiths commented Jun 3, 2022

@EmilSoleymani do you know the definition of DGWT in the code? Is it the same as z? Since DGWT/DX - FLOAT(I-1) is multiplied by DX, we get DGWT - FLOAT(I-1)*DX. Assuming that DX is constant, this does look like z_a, since I-1 seems to be the number of increments.

I remember we talked about keeping a file of inconsistencies that were found in the code/documentation. Did you start that file? We should be sure to have the GAW example in there. (It is worth noting that in Drasil we couldn't have this kind of inconsistency - it would either be right everywhere, or wrong everywhere.) 😄

@EmilSoleymani
Copy link
Collaborator

@smiths DGWT = depth to ground water table

@EmilSoleymani
Copy link
Collaborator

I think we can confidently state that we have completed our analysis of the FORTRAN code.

@smiths
Copy link
Owner Author

smiths commented Jul 6, 2022

Agreed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

2 participants