How can I close files for writing within a loop

I want to store output for a simulation. I want to be able to change the number of output files the code creates based on user input.

Here is what I have so far, everything is inside main:


function main()
out_loc = [5.0, 10.0, 15.0, 20.0, 25.0] # This will change based on what the user wants

for i in out_loc
    open(string(out_path, "time_series_depth_",i, "km.out"), "w") do i
	   write(i, "t slip sliprate shear_stress state")
end  # for

# Time loop of simulation
while t < tmax
    for i in 1:length(out_loc)
        write(string(out_loc[i]), join(hcat(t, slip, sliprate, shear_stress, state), " "), "\n")
    end # for

end # while

# Close the files
for i in out_loc
    end # the open statements
end # for

end # main

Having these end statements in the for loop somehow messes up and gives a variable scope error (it is possibly parsing the first end as end main function). Is there any efficient way to do this?

As always, thanks for any help :smile:

EDIT: Context: I have a very large fem simulation where I want to save multiple outputs based on some given receiver locations in the domain. The simulation takes hours (even days on a single computer), and storing those outputs in arrays is not feasible. Additionally, I can’t store everything in one file because it will be too big and messy to read. I would like to have 20-30 files for each simulation storing different variables at different locations. I am not allocating arrays for these outputs because the size is undetermined.

I fixed the comments in your code to indicate what the ends really correspond to.

Obviously there are issues here that need to be fixed. The last for loop is empty for example.

3 Likes

Here is the best that I can do. Basically for each element of out_loc we open a file, perform a simulation recording that file, and then we close the file. Then we repeat for the next element of out_loc.

const outpath = "/some/path"

function main()
    out_loc = [5.0, 10.0, 15.0, 20.0, 25.0] # This will change based on what the user wants
    
    # i will take on values 5, then 10, and so forth
    for i in out_loc
        open(joinpath(outpath,"time_series_depth_$i_km.out")), "w") do f
            write(f, "t slip sliprate shear_stress state")
            t = 0
            slip = 0
            shear_stress = 0
            state = 0
            while t < tmax
                t, slip, sliprate, shear_stress, state = perform_time_step(i, t, slip, shear_stress, state)
                println(f, "$t $slip $sliprate $shear_stress $state")
            end # while
        end # open ... do
    end # for
end # main

What is not clear to me is why you were trying to have multiple files open at the same time. Here we open one file at a time and focus on writing to that one file.

3 Likes

Now let’s say there is some reason that you really did need all those files open at the same time.

const outpath = "/some/path"

function main()
    out_loc = [5.0, 10.0, 15.0, 20.0, 25.0] # This will change based on what the user wants
    
    # open each file, and write a header
    # i is just counting, 1, 2, 3, ...
    # o is now the values in out_loc
    for (i, o) in enumerate(out_loc)
        # no do syntax
        f[i] = open(joinpath(outpath,"time_series_depth_$o_km.out")), "w")
        write(f[i], "t slip sliprate shear_stress state")
    end

    try
        t = 0
        slip = 0
        shear_stress = 0
        state = 0
        while t < tmax
            # I am very confused about what might be happening in this loop
            for (i,o) in enumerate(out_loc)
                t, slip, sliprate, shear_stress, state = perform_time_step(o, t, slip, shear_stress, state)
                println(f[i], "$t $slip $sliprate $shear_stress $state")
            end
        end
    finally
        # close each file
        for i in 1:length(f)
            close(f[i])
        end
    end
end
2 Likes

Thanks for the response. I have a very large fem simulation where I want to save multiple outputs based on some given receiver locations in the domain. The simulation takes hours (even days on a single computer), and storing those outputs in arrays is not feasible. Additionally, I can’t store everything in one file because it will be too big and messy to read. I would like to have 20-30 files for each simulation storing different variables at different locations. I am not allocating arrays for these outputs because the size is undetermined.

Thanks, this looks like exactly what I want. I’ll try it tomorrow morning and let you know how it works.