Converting Fortran to Matlab
good night; I am trying to convert some fortran code to matlab and I do not understand what
ist = grp%brp%faceIndicatorArray(-20) ien = grp%brp%faceIndicatorArray(-19)
means in the following subroutine. I am not used to negative indices in matlab so this (-20) and (-19) corresponds to which element or what in the array?? Here is the all subroutine:
subroutine calculateLiftAndDrag(grp,ivd,lift,drag,momentum) ! as the name says IMPLICIT NONE type(GridSolverData) :: grp type(InputVariablesData) :: ivd real :: lift,drag,momentum integer :: i,ist,ien,ip real :: flowTangent(2),flowNormal(2),wallTangent(2),wallNormal(2),r(2) real :: p,tau_t,tau_n,PI,alphaRad,sum lift = 0.0 drag = 0.0 momentum = 0.0 PI = 4.0*atan(1.0) alphaRad = ivd%alpha*PI/180. flowTangent(1) = cos(alphaRad) flowTangent(2) = sin(alphaRad) flowNormal(1) = - flowTangent(2) flowNormal(2) = flowTangent(1) ! inviscid faces ist = grp%brp%faceIndicatorArray(-20) ien = grp%brp%faceIndicatorArray(-19) do i=ist,ien ip = grp%brp%faceIndicatorArray(i) wallTangent(1) = grp%brp%faceTangentArray(ip,1) wallTangent(2) = grp%brp%faceTangentArray(ip,2) wallNormal(1) = -wallTangent(2) wallNormal(2) = wallTangent(1) p = grp%p(ip) r = grp%coordinates(ip,:)-ivd%momentumPoint lift = lift - 2.0*grp%wallLength(ip)*p(wallNormal(1)*flowNormal(1)+wallNormal(2)*flowNormal(2)) drag = drag - 2.0*grp%wallLength(ip)*p*(wallNormal(1)*flowTangent(1)+wallNormal(2)*flowTangent(2)) momentum = momentum - 2.0*grp%wallLength(ip)*p*(r(1)*wallNormal(2)-r(2)*wallNormal(1)) end do
If anyone can help, I would be glad. Thank you in advance.
You face an interesting quandary. The very fact that you are moving from Fortran 90/95 (unless the .faceIndicatorArray is part of a F2003 object and thus this is all more complicated) which is based on loops to matrix based system like MATLAB means that you are going to lose a lot of efficiency if you don't change the math involved. Assuming this efficiency loss is acceptable, then consider an alternative to clean up the code and make it easier to convert to something more flexible in the future.
When I've seen negative negative array indices like this in Fortran 90/95 simulation code it is a holdover from FORTRAN 77 code that was directly translated. Most of the time in the codes I've worked with the negative indices indicate ancillary data that isn't part of the data set, but due to the fact that FORTRAN 77 didn't have data structures, it kept the actual data and the ancillary data together. You can tell almost immediately that this code was directly converted from FORTRAN from the variable names:
Was done relatively recently along with the declaring of the variables:
integer :: i, ist, ien, ip
Which falls into the default of:
REAL(A-H, O-Z), INTEGER(I-N)
Armed with this knowledge, it should become pretty apparent that this was quickly converted to be used with the type structures.
Since I don't know what the entire set of structures that are represented in the GridSolverData type and the types it contains, I can only give you vague suggestions. The brp element likely stands for "brep" which is a common file type for this type of solver. I don't know what the rest of your negative array indices do, but it would be beneficial to split off the ancillary values into other arrays as it makes sense and use a classdef with a get/put method to switch what gets accessed when you use negative array indices.
This approach would, in the future, allow you to ween the code off of the use of these negative values in time after you more fully understand it, while allowing you to replicate the current capabilities.
Knowing the full definition of type(GridSolverData) will help. Fortran allows zero and negative array indices, but matlab does not.
When I convert this type of thing, I just end up adding (|the largest negative index used| + 1) to all indices of this array in matlab. For example, this fortran:
ist = grp%brp%faceIndicatorArray(-20); ien = grp%brp%faceIndicatorArray(-19);
might become this in matlab:
ist = grp.brp.faceIndicatorArray(-20+20+1); ien = grp.brp.faceIndicatorArray(-19+20+1);
And just do this throughout the subroutine. For example this would also change:
ip = grp%brp%faceIndicatorArray(i)
ip = grp.brp.faceIndicatorArray(i+20+1);