I was trying to do parametric studies in ABAQUS. I created an *.inp file (master) using GUI in abaqus, then wrote a matlab code to create a new *.inp file using the master. Master *.inp file can be found here and will be required to run the code.
In the new *.inp file everything was same as the master except a few specific lines which I am changing for parametric studies, code is given below. I am getting the files nicely but the problem is ABAQUS can't read the file and gives error messages. By visual inspection I don't find any faults. I guess matlab is writing the *.inp file in some other format which ABAQUS can't interpret.
clc;
%Number of lines to be copied
total_lines=4538; %total number of lines
lines_b4_RP1=4406; % lines before reference point 1
%creating new files
for A=0
for R=[20 30 40 50 100 200 300 400 500]
fileroot = sprintf('P_SHS_120X120X1_NLA_I15_A%dR%d.inp', A,R);
main_inp=fopen('P_SHS_120X120X1_NLA_I15_A0R10.inp','r'); %inputting the main inp file to be copied
wfile=fopen(fileroot,'w+'); %wfile= writing the new file
for i=1:total_lines
data=fgets(main_inp);
if i<lines_b4_RP1
fprintf(wfile,'%s\n', data);
elseif i==lines_b4_RP1
formatline1=('%s\n');
txtline='*Node';
fprintf(wfile, formatline1 ,txtline);
elseif i==(lines_b4_RP1+1)
formatline2=('%d%s%d%s%d%s%d\r\n');
comma=',';
refpt1=1;
xcoord1=R*cosd(A);
ycoord1=R*sind(A);
zcoord1=-20;
fprintf(wfile, formatline2, refpt1,comma,xcoord1,comma,ycoord1,comma,zcoord1);
elseif i==(lines_b4_RP1+2)
fprintf(wfile, formatline1 ,txtline);
elseif i==(lines_b4_RP1+3)
refpt2=2;
xcoord2=R*cosd(A);
ycoord2=R*sind(A);
zcoord2=420;
fprintf(wfile, formatline2 ,refpt2,comma,xcoord2,comma,ycoord2,comma,zcoord2);
elseif i>(lines_b4_RP1+3)
fprintf(wfile,'%s\n', data);
else break;
end
end
fclose(main_inp);
fclose(wfile);
end
end
Thanks in advance.
N.B. A sample *.dat file containing the error message is given here.
You are using fgets to get each line of the input file. From the matlab help:
fgets: Read line from file, keeping newline characters
You then print each line using
fprintf(wfile,'%s\n', data);
This creates two newlines at the end of each data line in the file. A second problem in your file is that you use \r\n in your format specifier. In matlab (unlike C) this will give you two newlines. e.g.
>> fprintf('Hello\rWorld\nFoo\r\nBar\n')
Hello
World
Foo
Bar
>>
I would suggest in future to test this approach with a much simpler format that you can use. Also there is a
*preprint
option that allows you to echo the contents of the input file back into the dat file. This creates big dat files, but it is useful for debugging.
Related
I need perform 50 Abaqus simulations, each simulation analyses a certain material property and each differs by changing one parameter. So the idea is to write a Matlab script that:
opens the .inp file
edits the material parameter of interest
prints it into a new file which will be the new .inp file
runs it to perform the simulation
This is what I accomplished so far in a very simplified version:
f= fopen('PRD8_30s.inp');
c = textscan(f,'%s %s %s %s %s ','delimiter',',');
fclose(f) ;
S = [c{1}];
A = {'5e-08'} ;
S(12496) = A ;
fid = fopen('file.inp','w') ;
fprintf(fid,'%s \n',S{:} );
fclose(fid) ;
PRD_8_30s.inp
I manually found out the position of the parameter of interest (A at 12496 hence below the line *Viscoelastic). The code actually changes the parameter I need but there are major problems: it prints a new file with additional lines with respect to the original .inp (12552 vs 8737) and it doesn't print the entire .inp but only the first column.
How can I edit the .inp changing the parameter and obtaining a new .inp with the edited parameter that can be used to run the new simulation?
Thank you in advance for your help!
If your input file is not multiple Gb in size, The following might help.
create a template input and mark the parameter you want to change as, for example para_xxxx
Use the following script:
text=fileread('template.inp');
newtext=replace(text,'para_xxxx',newParameter);
fid=fopen('newcase.inp','w');
fprintf(fid,newtext);
fclose(fid);
The file name 'newcase.inp' should be updated each time in the loop.
I am downloading some data in static and time series format using Matlab codes (and toolboxes). The codes give out the results by default in a .csv file for static and time series separately. Although the static data turns out fine, the time series data is huge and the .csv file doesn't load all the data. I tried changing the output file extension to .dta and then also .mat in order to view the output in Stata or Matlab. Also tried writing a little loop where the data loaded into large .csv file can be split into two worksheets within the same file. But none of it has worked. Although I am used to some basic coding in Matlab, I am new to dealing with such large datasets. Any help on this would be very much appreciated.
Thank you- Veronica
How about using these two bits of VBScript to split your CSV file into 2 pieces. There will be 599,999 lines in the first output file (part1.csv) and the rest in the second file (part2.csv).
Save this as part1.vbs
Set fso = CreateObject ("Scripting.FileSystemObject")
Set stdout = fso.GetStandardStream (1)
LineNum=1
Do While Not WScript.StdIn.AtEndOfStream
REM Read in next line of input
Line = WScript.StdIn.ReadLine()
If LineNum<600000 Then
stdout.WriteLine(Line)
End If
LineNum=LineNum+1
Loop
Save this as part2.vbs
Set fso = CreateObject ("Scripting.FileSystemObject")
Set stdout = fso.GetStandardStream (1)
LineNum=1
Do While Not WScript.StdIn.AtEndOfStream
REM Read in next line of input
Line = WScript.StdIn.ReadLine()
If LineNum>=600000 Then
stdout.WriteLine(Line)
End If
LineNum=LineNum+1
Loop
Then you can do this at the Command Prompt to split your file in two:
cscript /nologo part1.vbs YourFile.CSV > part1.csv
cscript /nologo part2.vbs YourFile.CSV > part2.csv
I am using MATLAB
I Have 51 files in their own directory all of .out extention created by a seperate program, all numbered 0 to 50.
ie
0.out
1.out
2.out
and so on til 50.out.
I need to load each file 1 by one to do calculations upon them within a for loop. How would I do this using the count variable to load the file, if the directory is set beforehand?
i.e.
%set directiory
cd(......)
%for loop
For count = 0:50,
data = count.out *<-----this line*
.....
Many thanks!
First generate the file name with
fileName = [int2str(count) '.out'];
then open the file with
fid = fopen(fileName, 'r');
The loading phase depends on the kind of file you want to read. Assuming it is a text file you can, for example, read it line after line with
while ~feof(fid)
line = fgetl(fid);
end
or use more specialized functions (see http://www.mathworks.it/it/help/matlab/text-files.html). Before the end of the for loop you'll have to close the file by calling
fclose(fid);
Another quite nice way to do it is to use the dir function
http://www.mathworks.co.uk/help/matlab/ref/dir.html
a = dir('c:\docs*.out')
Will give you a structure containing all the info about the *.out files in the directory you point it to, (or the path). You can then loop through it bit by bit. using fopen or csvread or whatever file reading function you want to use.
I have several data log files (here: 34) for those I have to calculate some certain values. I wrote a seperate function to publish the results of the calculation in a pdf file. But I only can publish one file after another, so it takes a while to publish all 34 files.
Now I want to automize that with a loop - importing the data, calculate the values and publish the results for every log file in a new pdf file. I want 34 pdf files for every log file at the end.
My problem is, that I couldn't find a way to rename the pdf files during publishing. The pdf file is always named after the script which is calculating the values. Obviously the pdf is overwritten within a loop. So at the end everything is calculated, but I only have the pdf from the last calculated log file.
There was this hacky solution to change the Matlab publish script, but since I don't have admin rights I can't use that:
"This is really hacky, but I would modify publish to accept a new option prefix. Replace line 93
[scriptDir,prefix] = fileparts(fullPathToScript);
with
if ~isfield(options, 'prefix')
[scriptDir,prefix] = fileparts(fullPathToScript);
else
[scriptDir,~] = fileparts(fullPathToScript);
prefix = options.prefix; end
Now you can set options.prefix to whatever filename you want. If you want to be really hardcore, make the appropriate modifications to supplyDefaultOptions and checkOptionFields as well."
Any suggestions?
Thanks in advance,
Martin
Here's one idea using movefile to rename the resultant published PDF on each iteration:
for i = 1:34
file = publish(files(i)); % Replace with your own command(s)
[pathStr,fileName,ext] = fileparts(file);
newFile = [pathStr filesep() fileName '_' int2str(i) ext]; % Example: append _# to each
[success,msg,msgid] = movefile(file,newFile);
if ~success
error(msgid,msg);
end
end
Also used are fileparts and filesep. See this question for other ways to rename and move files.
I have a file full of ascii data. How would I append a string to the first line of the file? I cannot find that sort of functionality using fopen (it seems to only append at the end and nothing else.)
The following is a pure MATLAB solution:
% write first line
dlmwrite('output.txt', 'string 1st line', 'delimiter', '')
% append rest of file
dlmwrite('output.txt', fileread('input.txt'), '-append', 'delimiter', '')
% overwrite on original file
movefile('output.txt', 'input.txt')
Option 1:
I would suggest calling some system commands from within MATLAB. One possibility on Windows is to write your new line of text to its own file and then use the DOS for command to concatenate the two files. Here's what the call would look like in MATLAB:
!for %f in ("file1.txt", "file2.txt") do type "%f" >> "new.txt"
I used the ! (bang) operator to invoke the command from within MATLAB. The command above sequentially pipes the contents of "file1.txt" and "file2.txt" to the file "new.txt". Keep in mind that you will probably have to end the first file with a new line character to get things to append correctly.
Another alternative to the above command would be:
!for %f in ("file2.txt") do type "%f" >> "file1.txt"
which appends the contents of "file2.txt" to "file1.txt", resulting in "file1.txt" containing the concatenated text instead of creating a new file.
If you have your file names in strings, you can create the command as a string and use the SYSTEM command instead of the ! operator. For example:
a = 'file1.txt';
b = 'file2.txt';
system(['for %f in ("' b '") do type "%f" >> "' a '"']);
Option 2:
One MATLAB only solution, in addition to Amro's, is:
dlmwrite('file.txt',['first line' 13 10 fileread('file.txt')],'delimiter','');
This uses FILEREAD to read the text file contents into a string, concatenates the new line you want to add (along with the ASCII codes for a carriage return and a line feed/new line), then overwrites the original file using DLMWRITE.
I get the feeling Option #1 might perform faster than this pure MATLAB solution for huge text files, but I don't know that for sure. ;)
How about using the frewind(fid) function to take the pointer to the beginning of the file?
I had a similar requirement and tried frewind() followed by the necessary fprintf() statement.
But, warning: It will overwrite on whichever is the 1st line. Since in my case, I was the one writing the file, I put a dummy data at the starting of the file and then at the end, let that be overwritten after the operations specified above.
BTW, even I am facing one problem with this solution, that, depending on the length(/size) of the dummy data and actual data, the program either leaves part of the dummy data on the same line, or bring my new data to the 2nd line..
Any tip in this regards is highly appreciated.