cronoscrmod 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ac201c7e381fe074df24db61e63e60df5c17151a
4
+ data.tar.gz: 32b3cfde01015ce590dbdf152297d66496c74c31
5
+ SHA512:
6
+ metadata.gz: 4ab19a83935902bce67fcceb114b70bdc78d8b5c83438e6193b4372f9268b90a81d659bdb2580dc58e01a8ed4900267e8f4253d40f661c0b46eb1e93a3895d8b
7
+ data.tar.gz: 939ca19f7861e41e1f909852c20eda13b305a953abaa311c378efa290d11a0969000cf8e1fdb89e2dfe18229125756a848768302003f262456f63588e56022a0
data/Gemfile CHANGED
@@ -2,15 +2,14 @@ source "http://rubygems.org"
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
- gem "coderunner", ">= 0.13.18"
5
+ gem "coderunner", ">= 1.0"
6
6
  #gem "matlab-ruby", "> 2.0.0"
7
7
 
8
8
  # Add dependencies to develop your gem here.
9
9
  # Include everything needed to run rake, tests, features, etc.
10
10
  group :development do
11
- gem "shoulda", ">= 0"
11
+ gem "shoulda", "~> 3.5"
12
12
  gem "rdoc", "~> 3.12"
13
- gem "bundler", "> 1.0.0"
14
- gem "jeweler", ">= 1.8.4"
15
- #gem "rcov", ">= 0"
13
+ #gem "bundler", "> 1.0.0"
14
+ gem "jeweler", "~> 2.3"
16
15
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
data/cronoscrmod.gemspec CHANGED
@@ -2,16 +2,18 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
+ # stub: cronoscrmod 0.1.2 ruby lib
5
6
 
6
7
  Gem::Specification.new do |s|
7
- s.name = "cronoscrmod"
8
- s.version = "0.1.1"
8
+ s.name = "cronoscrmod".freeze
9
+ s.version = "0.1.2"
9
10
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Edmund Highcock"]
12
- s.date = "2013-10-17"
13
- s.description = "A module to allow CodeRunner to run the integrated tokamak modelling suite Cronos. Requires matlab and matlab-ruby (Cronos also requires Matlab)."
14
- s.email = "edmundhighcock@users.sourceforge.net"
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib".freeze]
13
+ s.authors = ["Edmund Highcock".freeze]
14
+ s.date = "2017-01-16"
15
+ s.description = "A module to allow CodeRunner to run the integrated tokamak modelling suite Cronos. Requires matlab and matlab-ruby (Cronos also requires Matlab).".freeze
16
+ s.email = "edmundhighcock@users.sourceforge.net".freeze
15
17
  s.extra_rdoc_files = [
16
18
  "LICENSE.txt",
17
19
  "README.md",
@@ -30,37 +32,36 @@ Gem::Specification.new do |s|
30
32
  "lib/cronoscrmod.rb",
31
33
  "lib/cronoscrmod/cronos.rb",
32
34
  "lib/cronoscrmod/defaults_files/cronos_defaults.rb",
35
+ "lib/cronoscrmod/matlab/cronos_eqdsk.m",
36
+ "lib/cronoscrmod/matlab/eqdsk_jc.m",
37
+ "lib/cronoscrmod/matlab/output_ogyropsi.m",
33
38
  "test/helper.rb",
34
39
  "test/test_cronoscrmod.rb"
35
40
  ]
36
- s.homepage = "http://github.com/edmundhighcock/cronoscrmod"
37
- s.licenses = ["MIT"]
38
- s.require_paths = ["lib"]
39
- s.rubygems_version = "1.8.23"
40
- s.summary = "A module to allow CodeRunner to run the integrated tokamak modelling suite Cronos"
41
+ s.homepage = "http://github.com/edmundhighcock/cronoscrmod".freeze
42
+ s.licenses = ["MIT".freeze]
43
+ s.rubygems_version = "2.6.8".freeze
44
+ s.summary = "A module to allow CodeRunner to run the integrated tokamak modelling suite Cronos".freeze
41
45
 
42
46
  if s.respond_to? :specification_version then
43
- s.specification_version = 3
47
+ s.specification_version = 4
44
48
 
45
49
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
46
- s.add_runtime_dependency(%q<coderunner>, [">= 0.13.18"])
47
- s.add_development_dependency(%q<shoulda>, [">= 0"])
48
- s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
49
- s.add_development_dependency(%q<bundler>, ["> 1.0.0"])
50
- s.add_development_dependency(%q<jeweler>, [">= 1.8.4"])
50
+ s.add_runtime_dependency(%q<coderunner>.freeze, [">= 1.0"])
51
+ s.add_development_dependency(%q<shoulda>.freeze, ["~> 3.5"])
52
+ s.add_development_dependency(%q<rdoc>.freeze, ["~> 3.12"])
53
+ s.add_development_dependency(%q<jeweler>.freeze, ["~> 2.3"])
51
54
  else
52
- s.add_dependency(%q<coderunner>, [">= 0.13.18"])
53
- s.add_dependency(%q<shoulda>, [">= 0"])
54
- s.add_dependency(%q<rdoc>, ["~> 3.12"])
55
- s.add_dependency(%q<bundler>, ["> 1.0.0"])
56
- s.add_dependency(%q<jeweler>, [">= 1.8.4"])
55
+ s.add_dependency(%q<coderunner>.freeze, [">= 1.0"])
56
+ s.add_dependency(%q<shoulda>.freeze, ["~> 3.5"])
57
+ s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
58
+ s.add_dependency(%q<jeweler>.freeze, ["~> 2.3"])
57
59
  end
58
60
  else
59
- s.add_dependency(%q<coderunner>, [">= 0.13.18"])
60
- s.add_dependency(%q<shoulda>, [">= 0"])
61
- s.add_dependency(%q<rdoc>, ["~> 3.12"])
62
- s.add_dependency(%q<bundler>, ["> 1.0.0"])
63
- s.add_dependency(%q<jeweler>, [">= 1.8.4"])
61
+ s.add_dependency(%q<coderunner>.freeze, [">= 1.0"])
62
+ s.add_dependency(%q<shoulda>.freeze, ["~> 3.5"])
63
+ s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
64
+ s.add_dependency(%q<jeweler>.freeze, ["~> 2.3"])
64
65
  end
65
66
  end
66
67
 
@@ -38,7 +38,12 @@ class CodeRunner
38
38
  def cronos(*args)
39
39
  if args.size > 0
40
40
  args.each do |com|
41
- CodeRunner::Cronos.rcp.engine_handler.cronos.puts(com)
41
+ begin
42
+ CodeRunner::Cronos.rcp.engine_handler.cronos.puts(com)
43
+ rescue Errno::EPIPE
44
+ CodeRunner::Cronos.rcp.engine_handler.restart_cronos(@r.executable.sub(/cronos$/, ""))
45
+ retry
46
+ end
42
47
  end
43
48
  end
44
49
  end
@@ -58,8 +63,13 @@ class CodeRunner
58
63
  return if @cronos_started
59
64
  raise "cronos not found in #{path}" unless FileTest.exist?("#{path}/cronos.m")
60
65
  @cronos = IO.popen("#{path}/cronos 3>&2 2>&1 1>&3 | grep -v 'Time Machine' 3>&2 2>&1 1>&3 ", 'w')
66
+ @cronos.puts("addpath('#{CodeRunner::Cronos.rcp.code_module_folder}/matlab')")
61
67
  @cronos_started = true
62
68
  end
69
+ def restart_cronos(path)
70
+ @cronos_started = false
71
+ start_cronos(path)
72
+ end
63
73
  def new_file
64
74
  @cronos.puts("zuicreate")
65
75
  end
@@ -181,6 +191,11 @@ class CodeRunner
181
191
  refresh_gui
182
192
  end
183
193
 
194
+ def load_result
195
+ cronos.puts("zuiload('#@directory/#{@run_name}_resultat.mat')")
196
+ refresh_gui
197
+ end
198
+
184
199
  def cronos
185
200
  set_cronos_path
186
201
  rcp.engine_handler.cronos
@@ -0,0 +1,276 @@
1
+ function no_results = cronos_eqdsk(data, fname, tavg, resofactor)
2
+ %CREATES A EFIT EQDSK G FILE AND MATLABSTRUCTURE FROM CRONOS DATA.EQUI DATA. USED FOR CREATING
3
+ %GEOMETRY INPUT FILES FOR GENE. ALSO CREATES CONVENIENT MATLAB STRUCTURE WITH KEY INFORMATION
4
+ %
5
+ %A CRONOS DATA FILE NEEDS TO BE IN THE BACKGROUND WHEN RUNNING THIS ROUTINE
6
+ %J.Citrin 20.05.2013
7
+
8
+
9
+ %%%%%%%%%%%%INPUT PARAMETERS%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10
+ %fname='JET75225_Ptotred'; %choose a name for the output geometry file
11
+ %tavg=[46 47]; %choose a time window for averaging of CRONOS data
12
+ printflag=0; %flag to plot or not (=1) or not to plot (anything else) a figure of the 2D flux surfaces
13
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14
+
15
+
16
+ bleed=0.02; %space around limits of R,Z points to define the rectangular grid
17
+
18
+ ind=round(interp1(data.gene.temps,1:length(data.gene.temps),tavg)); ind=ind(1):ind(2); %find the indexes in data.gene.temps of the desired time window
19
+ x=linspace(0,1,101);
20
+
21
+ %obtain R,Z, and psi from data.equi. Note that the normalized radial coordinate below is from equi.rhoRZ./equi.rhoRZ(end) and not the uniform x!
22
+ R=squeeze(mean(data.equi.R(ind,:,:))); R=double(R);
23
+ Z=squeeze(mean(data.equi.Z(ind,:,:))); Z=double(Z);
24
+ psiequi=-mean(data.equi.psiRZ(ind,:)); psiequi=(double(psiequi)); %the minus sign is there since eqdsk expects flipped psi profiles
25
+ resotheta=length(R(1,:)); %finds the theta resolution from the CRONOS simulation
26
+
27
+ %JC 15.5.13
28
+ %TO BE CONSISTENT WITH THE CHEASE EQDSK DATA, PSIEQUI IS SHIFTED SUCH THAT PSIEQUI(1)=0
29
+ %FEEL FREE TO CHANGE THIS, IT IS TRIVIAL TO DO SO
30
+ psiequi=psiequi-psiequi(1);
31
+ %psiequi=psiequi-psiequi(end);
32
+ xrho=mean(data.equi.rhoRZ(ind,:)); xrho=xrho./xrho(end);
33
+ psix=interp1(xrho,psiequi,x);
34
+ rho1=mean(data.equi.rhomax(ind));
35
+
36
+ %set the resolution of the rectangular box (for now kept the same as the theta resolution from cronos)
37
+ resoR=resotheta*resofactor;
38
+ resoZ=resotheta*resofactor;
39
+ resopsi=resotheta*resofactor;
40
+
41
+ %resoR=100;
42
+ %resoZ=100;
43
+ %resopsi=65;
44
+
45
+ %interpolate equi.psi onto the uniform toroidal flux grid and create
46
+ %the normalized poloidal flux coordinate to interpolate the q, P, P', F, FF' profiles
47
+ xrho=mean(data.equi.rhoRZ(ind,:)); xrho=xrho./xrho(end); xrho=double(xrho);
48
+ psix=interp1(xrho,psiequi,x, 'splines');
49
+ psinormx=(psix-psix(1))./(psix(end)-psix(1));
50
+ psinormequi = (psiequi-psiequi(1))./(psiequi(end) - psiequi(1));
51
+ dvdrho=mean(data.equi.vpr(ind,:));
52
+ %create desired uniform normalized poloidal flux grid
53
+ xpsi=linspace(0,1,resopsi);
54
+
55
+
56
+
57
+ %define boundaries of rectangular grid
58
+ maxR=max(max(R))+bleed;
59
+ minR=min(min(R))-bleed;
60
+ maxZ=max(max(Z))+bleed;
61
+ minZ=min(min(Z))-bleed;
62
+
63
+ maxxZ = max([maxZ, -minZ]);
64
+ maxZ = maxxZ;
65
+ minZ = -maxxZ;
66
+
67
+ %create rectangular grid
68
+ xR=linspace(minR,maxR,resoR);
69
+ % EGH Z is defined from - to plus, and it must also be symmetric
70
+ yR=linspace(minZ,maxZ,resoZ);
71
+ [xnodes,ynodes] = meshgrid(xR,yR); %xnodes, ynodes are matrices defining the x and y (R and Z) coordinates
72
+
73
+ %Create a 2D array for psi corresponding to x,theta (is a flux function, so same at every theta and tmp is discarded)
74
+ %This 2D array, which fits the x,theta arrays of R,Z, are interpolated onto the rectangular grid with coordinates xnodes,ynodes
75
+ [psibig,tmp]=meshgrid(psiequi,1:resotheta); psibig=psibig';
76
+ zefit1 = griddata(R,Z,psibig,xnodes,ynodes,'cubic');
77
+
78
+ %define psi quantities for all points in rectangular grid that lay outside of separatrix (became NaN in interpolation)
79
+ zefit1(isnan(zefit1))=psiequi(end)*1.05;
80
+
81
+ %grab necessary profiles and interpolate onto normalized poloidal flux grid
82
+ qraw=mean(data.equi.q(ind,:)); qraw=double(qraw);
83
+ s=mean(data.equi.shear(ind,:));
84
+ F=mean(data.equi.F(ind,:));
85
+ P=mean(data.prof.ptot(ind,:));
86
+ %FFprime=gradient(F,-psiequi); %the minus sign on psiequi defines the gradient to the ORIGINAL psi (i.e. the unflipped one)
87
+ % EGH Bugfix
88
+ % F and P are on grids of x not rho, so need to take gradient wrt psix
89
+ FFprime=gradient(F,psix); %the minus sign on psiequi defines the gradient to the ORIGINAL psi (i.e. the unflipped one)
90
+ Pprime=gradient(P,psix);
91
+
92
+ % Values of psi on the output grid of xpsi
93
+ psixpsi = interp1(psinormequi, psiequi, xpsi);
94
+
95
+ q=interp1(psinormx,qraw,xpsi);
96
+ F=interp1(psinormx,F,xpsi, 'spline');
97
+ FFprime=interp1(psinormx,FFprime,xpsi).*F; %FFprime(1) = 0.0;
98
+ %FFprime = gradient(F, psixpsi).*F;
99
+ %FFprime = interp1(psinormequi, mean(squeeze(data.equi.df2RZ(ind, :)))*pi, xpsi);
100
+ %FFprime(1)=(FFprime(1)+FFprime(2))/2.0;
101
+ FFprime(3) = FFprime(4);
102
+ FFprime(2) = FFprime(3);
103
+ FFprime(1) = FFprime(2);
104
+ %FFprime(1) = 0.0;
105
+ P=interp1(psinormx,P,xpsi, 'spline');
106
+ Pprime=interp1(psinormx,Pprime,xpsi); %Pprime(1) = 0.0;
107
+ %Pprime = interp1(psinormequi, mean(squeeze(data.equi.dprRZ(ind, :)))*-300000, xpsi);
108
+ %Pprime=gradient(P, psixpsi);
109
+ %Pprime(1)=(Pprime(1)+Pprime(2))/2.0;
110
+ %Pprime(1)=Pprime(2)/2.0;
111
+ Pprime(3)=Pprime(4);
112
+ Pprime(2)=Pprime(3);
113
+ Pprime(1)=Pprime(2);
114
+ %Pprime(1) = 0.0;
115
+
116
+ %define header quantities for eqdsk file
117
+ boxw=maxR-minR;
118
+ boxh=maxZ-minZ;
119
+ rmaj=(maxR+minR)/2;
120
+ rleft=minR;
121
+
122
+ zmid=(maxZ+minZ)/2;
123
+ zmaxis=Z(1,1);
124
+
125
+
126
+ %ZMID AND ZMAXIS SWITCHED TO ZERO TO BE CONSISTENT WITH THE CHEASE EQDSK INFO
127
+ %zmid=0;
128
+ %zmaxis=0;
129
+
130
+
131
+ %IT IS RECOMMENDED TO LEAVE RMAXIS AS IS, SINCE THIS PROVIDES INFORMATION ON THE SHAFRANOV SHIFT
132
+ rmaxis1=R(1,1);
133
+ psiAxis=psiequi(1);
134
+ %psiSep=psi(end)/1.05; %TEMP FIX
135
+ psiSep=psiequi(end);
136
+ B=mean(data.geo.b0(ind));
137
+ Ip=mean(data.gene.ip(ind))/1e6;
138
+ Ip=mean(data.gene.ip(ind));
139
+
140
+ fid1 = fopen(fname, 'w');
141
+
142
+ %write header quantities
143
+ %fprintf(fid1, ' JET EFIT TRACER %d %d %d\n',0,resoR,resoZ);
144
+ fprintf(fid1, ' JET EFIT FILE FROM CRONOS %d%4d%4d\n',0,resoR,resoZ);
145
+ fprintf(fid1,'% 16.9E% 16.9E% 16.9E% 16.9E% 16.9E\n% 16.9E% 16.9E% 16.9E% 16.9E% 16.9E\n% 16.9E% 16.9E% 16.9E% 16.9E% 16.9E\n% 16.9E% 16.9E% 16.9E% 16.9E% 16.9E\n',...
146
+ boxw,boxh,rmaj,rleft,zmid,rmaxis1,zmaxis,psiAxis,psiSep,B,Ip,psiAxis,0,rmaxis1,0,zmaxis,0,psiSep,0,0);;
147
+
148
+ %write F, FF', P, P' quantities
149
+ for k=1:resopsi
150
+ fprintf(fid1,'% 16.9E',F(k));
151
+ if mod(k,5)==0
152
+ fprintf(fid1,'\n');
153
+ end
154
+ end
155
+
156
+ for k=1:resopsi
157
+ fprintf(fid1,'% 16.9E',P(k));
158
+ if mod(k,5)==0
159
+ fprintf(fid1,'\n');
160
+ end
161
+ end
162
+
163
+ for k=1:resopsi
164
+ fprintf(fid1,'% 16.9E',FFprime(k));
165
+ if mod(k,5)==0
166
+ fprintf(fid1,'\n');
167
+ end
168
+ end
169
+
170
+ for k=1:resopsi
171
+ fprintf(fid1,'% 16.9E',Pprime(k));
172
+ if mod(k,5)==0
173
+ fprintf(fid1,'\n');
174
+ end
175
+ end
176
+
177
+ %write poloidal flux onto rectangular grid
178
+ for j=1:resoZ
179
+ for k=1:resoR
180
+ fprintf(fid1,'% 16.9E',zefit1(j,k));
181
+ if mod(k,5)==0
182
+ fprintf(fid1,'\n');
183
+ end
184
+ end
185
+ end
186
+
187
+ %write the q-profile
188
+ for k=1:resopsi
189
+ fprintf(fid1,'% 16.9E',q(k));
190
+ if mod(k,5)==0
191
+ fprintf(fid1,'\n');
192
+ end
193
+ end
194
+
195
+ fprintf(fid1, ' %d %d \n', resotheta-1, 1);
196
+ j = 1
197
+ for k=1:(resotheta-1)
198
+ fprintf(fid1, '% 16.9E', R(end, k));
199
+ if mod(j,5)==0
200
+ fprintf(fid1, '\n');
201
+ end
202
+ j = j + 1;
203
+ fprintf(fid1, '% 16.9E', Z(end, k));
204
+ if mod(j,5)==0
205
+ fprintf(fid1, '\n');
206
+ end
207
+ j = j + 1;
208
+ end
209
+ if mod(j-1,5)~=0
210
+ fprintf(fid1, '\n');
211
+ end
212
+
213
+ fprintf(fid1, ' %16.9E %16.9E \n', 0.0, 0.0);
214
+
215
+
216
+
217
+ fclose(fid1);
218
+
219
+
220
+ %%%PLOT FLUX SURFACES FROM JUST MADE EQDSK FILE
221
+
222
+ fid=fopen(fname);
223
+ fseek(fid, 60, 'bof');
224
+ p=fscanf(fid,'%f');
225
+ fclose(fid);
226
+ pars=p(1:20);
227
+ p(1:20)=[];
228
+ p(1:resopsi*4)=[];
229
+ xefit=linspace(0,1,resopsi);
230
+ qefit=p(resoR*resoZ+1:end);
231
+ for j=1:resoZ
232
+ for k=1:resoR
233
+ psiefit(j,k)=p(resoR*(j-1)+k,1);
234
+
235
+ end
236
+ end
237
+
238
+ %2D poloidal flux on R,Z grid
239
+ eval([fname,'.psi2D=psiefit;']);
240
+
241
+ %poloidal flux on the magnetic axis and the last-closed-flux surface
242
+ eval([fname,'.psiaxis=psiequi(1);']);
243
+ eval([fname,'.psiedge=psiequi(end);']);
244
+
245
+ %major radius
246
+ eval([fname,'.r0=rmaj;']);
247
+
248
+ %radius of the magnetic axis (difference between raxis and r0 is the Shafranov shift)
249
+ eval([fname,'.raxis=rmaxis1;']);
250
+
251
+ %z location of the geometric and magnetic axis center. If they are not the same it just means that the magnetic geometry is not up-down symmetric (which is common)
252
+ eval([fname,'.zmid=zmid;']);
253
+ eval([fname,'.zaxis=zmaxis;']);
254
+
255
+ %R and Z grids for the 2D psi
256
+ eval([fname,'.rmesh=xnodes(1,:)'';']);
257
+ eval([fname,'.zmesh=ynodes(:,1);']);
258
+
259
+ %Normalized toroidal flux coordinate grid
260
+ eval([fname,'.rhonorm=linspace(0,1,101);']);
261
+
262
+ %Toroidal flux on the last-closed-flux surface
263
+ eval([fname,'.rhoedge=rho1;']);
264
+
265
+ %1D psi on the toroidal flux grid
266
+ eval([fname,'.psi1D=psix;']);
267
+
268
+ %dvdrho on the toroidal flux grid
269
+ eval([fname,'.dvdrho=dvdrho;']);
270
+
271
+ eval(['save(''',fname,''');']);
272
+
273
+ %quick automatic contour plot of 2D flux surfaces
274
+ if printflag==1
275
+ figure; contour(xnodes,ynodes,psiefit,40); axis equal
276
+ end
@@ -0,0 +1,226 @@
1
+ function no_results = eqdsk_jc(data, fname, tavg, resofactor)
2
+ %CREATES A EFIT EQDSK G FILE AND MATLAB STRUCTURE FROM CRONOS DATA.EQUI DATA. USED FOR CREATING
3
+ %GEOMETRY INPUT FILES FOR GENE. ALSO CREATES CONVENIENT MATLAB STRUCTURE WITH KEY INFORMATION
4
+ %
5
+ %A CRONOS DATA FILE NEEDS TO BE IN THE BACKGROUND WHEN RUNNING THIS ROUTINE
6
+ %J.Citrin 20.05.2013
7
+
8
+ disp('Version 2.2');
9
+
10
+
11
+ %%%%%%%%%%%%INPUT PARAMETERS%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12
+ %fname='JET75225_Ptotred'; %choose a name for the output geometry file
13
+ %tavg=[46 47]; %choose a time window for averaging of CRONOS data
14
+ printflag=1; %flag to plot or not (=1) or not to plot (anything else) a figure of the 2D flux surfaces
15
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16
+
17
+
18
+ bleed=0.02; %space around limits of R,Z points to define the rectangular grid
19
+
20
+ ind=round(interp1(data.gene.temps,1:length(data.gene.temps),tavg)); ind=ind(1):ind(2); %find the indexes in data.gene.temps of the desired time window
21
+ x=linspace(0,1,101);
22
+
23
+ %obtain R,Z, and psi from data.equi. Note that the normalized radial coordinate below is from equi.rhoRZ./equi.rhoRZ(end) and not the uniform x!
24
+ R=squeeze(mean(data.equi.R(ind,:,:))); R=double(R);
25
+ Z=squeeze(mean(data.equi.Z(ind,:,:))); Z=double(Z);
26
+ psiequi=-mean(data.equi.psiRZ(ind,:)); psiequi=(double(psiequi)); %the minus sign is there since eqdsk expects flipped psi profiles
27
+ resotheta=length(R(1,:)); %finds the theta resolution from the CRONOS simulation
28
+
29
+ %JC 15.5.13
30
+ %TO BE CONSISTENT WITH THE CHEASE EQDSK DATA, PSIEQUI IS SHIFTED SUCH THAT PSIEQUI(1)=0
31
+ %FEEL FREE TO CHANGE THIS, IT IS TRIVIAL TO DO SO
32
+ %psiequi=psiequi-psiequi(1);
33
+ %psiequi=psiequi-psiequi(end);
34
+ xrho=mean(data.equi.rhoRZ(ind,:)); xrho=xrho./xrho(end);
35
+ psix=interp1(xrho,psiequi,x);
36
+ rho1=mean(data.equi.rhomax(ind));
37
+
38
+ %set the resolution of the rectangular box (for now kept the same as the theta resolution from cronos)
39
+ resoR=resotheta;
40
+ resoZ=resotheta;
41
+ resopsi=resotheta;
42
+
43
+ %resoR=100;
44
+ %resoZ=100;
45
+ %resopsi=65;
46
+
47
+ %interpolate equi.psi onto the uniform toroidal flux grid and create
48
+ %the normalized poloidal flux coordinate to interpolate the q, P, P', F, FF' profiles
49
+ xrho=mean(data.equi.rhoRZ(ind,:)); xrho=xrho./xrho(end); xrho=double(xrho);
50
+ psix=interp1(xrho,psiequi,x);
51
+ psinormx=(psix-psix(1))./(psix(end)-psix(1));
52
+ dvdrho=mean(data.equi.vpr(ind,:));
53
+ %create desired uniform normalized poloidal flux grid
54
+ xpsi=linspace(0,1,resopsi);
55
+
56
+
57
+ %define boundaries of rectangular grid
58
+ maxR=max(max(R))+bleed;
59
+ minR=min(min(R))-bleed;
60
+ maxZ=max(max(Z))+bleed;
61
+ minZ=min(min(Z))-bleed;
62
+
63
+ %create rectangular grid
64
+ xR=linspace(minR,maxR,resoR); yR=linspace(maxZ,minZ,resoZ);
65
+ [xnodes,ynodes] = meshgrid(xR,yR); %xnodes, ynodes are matrices defining the x and y (R and Z) coordinates
66
+
67
+ %Create a 2D array for psi corresponding to x,theta (is a flux function, so same at every theta and tmp is discarded)
68
+ %This 2D array, which fits the x,theta arrays of R,Z, are interpolated onto the rectangular grid with coordinates xnodes,ynodes
69
+ [psibig,tmp]=meshgrid(psiequi,1:resotheta); psibig=psibig';
70
+ zefit1 = griddata(R,Z,psibig,xnodes,ynodes,'cubic');
71
+
72
+ %define psi quantities for all points in rectangular grid that lay outside of separatrix (became NaN in interpolation)
73
+ zefit1(isnan(zefit1))=psiequi(end)*1.05;
74
+
75
+ %grab necessary profiles and interpolate onto normalized poloidal flux grid
76
+ qraw=mean(data.equi.q(ind,:)); qraw=double(qraw);
77
+ s=mean(data.equi.shear(ind,:));
78
+ F=mean(data.equi.F(ind,:));
79
+ P=mean(data.prof.ptot(ind,:));
80
+ %FFprime=-gradient(F,-psiequi).*F; %the minus sign on psiequi defines the gradient to the ORIGINAL psi (i.e. the unflipped one)
81
+ FFprime=gradient(F,-psiequi); %the minus sign on psiequi defines the gradient to the ORIGINAL psi (i.e. the unflipped one)
82
+ Pprime=gradient(F,-psiequi);
83
+ %Pprime=-gradient(P,-psiequi);
84
+
85
+ q=interp1(psinormx,qraw,xpsi);
86
+ F=interp1(psinormx,F,xpsi);
87
+ FFprime=interp1(psinormx,FFprime,xpsi); FFprime(1)=FFprime(2);
88
+ P=interp1(psinormx,P,xpsi);
89
+ Pprime=interp1(psinormx,Pprime,xpsi); Pprime(1)=Pprime(2);
90
+
91
+ %define header quantities for eqdsk file
92
+ boxw=maxR-minR;
93
+ boxh=maxZ-minZ;
94
+ rmaj=(maxR+minR)/2;
95
+ rleft=minR;
96
+
97
+ zmid=(maxZ+minZ)/2;
98
+ zmaxis=Z(1,1);
99
+
100
+ %ZMID AND ZMAXIS SWITCHED TO ZERO TO BE CONSISTENT WITH THE CHEASE EQDSK INFO
101
+ %zmid=0;
102
+ %zmaxis=0;
103
+
104
+
105
+ %IT IS RECOMMENDED TO LEAVE RMAXIS AS IS, SINCE THIS PROVIDES INFORMATION ON THE SHAFRANOV SHIFT
106
+ rmaxis1=R(1,1);
107
+ psiAxis=psiequi(1);
108
+ %psiSep=psi(end)/1.05; %TEMP FIX
109
+ psiSep=psiequi(end);
110
+ B=mean(data.geo.b0(ind));
111
+ Ip=mean(data.gene.ip(ind))/1e6;
112
+
113
+ fid1 = fopen(fname, 'w');
114
+
115
+ %write header quantities
116
+ fprintf(fid1, ' JET EFIT TRACER %d %d %d\n',0,resoR,resoZ);
117
+ fprintf(fid1,'% 16.9E% 16.9E% 16.9E% 16.9E% 16.9E\n% 16.9E% 16.9E% 16.9E% 16.9E% 16.9E\n% 16.9E% 16.9E% 16.9E% 16.9E% 16.9E\n% 16.9E% 16.9E% 16.9E% 16.9E% 16.9E\n',...
118
+ boxw,boxh,rmaj,rleft,zmid,rmaxis1,zmaxis,psiAxis,psiSep,B,0,psiAxis,0,rmaxis1,0,zmaxis,0,psiSep,0,0);;
119
+
120
+ %write F, FF', P, P' quantities
121
+ for k=1:resopsi
122
+ fprintf(fid1,'% 16.9E',F(k));
123
+ if mod(k,5)==0
124
+ fprintf(fid1,'\n');
125
+ end
126
+ end
127
+
128
+ for k=1:resopsi
129
+ fprintf(fid1,'% 16.9E',P(k));
130
+ if mod(k,5)==0
131
+ fprintf(fid1,'\n');
132
+ end
133
+ end
134
+
135
+ for k=1:resopsi
136
+ fprintf(fid1,'% 16.9E',FFprime(k));
137
+ if mod(k,5)==0
138
+ fprintf(fid1,'\n');
139
+ end
140
+ end
141
+
142
+ for k=1:resopsi
143
+ fprintf(fid1,'% 16.9E',Pprime(k));
144
+ if mod(k,5)==0
145
+ fprintf(fid1,'\n');
146
+ end
147
+ end
148
+
149
+ %write poloidal flux onto rectangular grid
150
+ for j=1:resoZ
151
+ for k=1:resoR
152
+ fprintf(fid1,'% 16.9E',zefit1(j,k));
153
+ if mod(k,5)==0
154
+ fprintf(fid1,'\n');
155
+ end
156
+ end
157
+ end
158
+
159
+ %write the q-profile
160
+ for k=1:resopsi
161
+ fprintf(fid1,'% 16.9E',q(k));
162
+ if mod(k,5)==0
163
+ fprintf(fid1,'\n');
164
+ end
165
+ end
166
+
167
+ fclose(fid1);
168
+
169
+
170
+ %%%PLOT FLUX SURFACES FROM JUST MADE EQDSK FILE
171
+
172
+ fid=fopen(fname);
173
+ fseek(fid, 60, 'bof');
174
+ p=fscanf(fid,'%f');
175
+ fclose(fid);
176
+ pars=p(1:20);
177
+ p(1:20)=[];
178
+ p(1:resopsi*4)=[];
179
+ xefit=linspace(0,1,resopsi);
180
+ qefit=p(resoR*resoZ+1:end);
181
+ for j=1:resoZ
182
+ for k=1:resoR
183
+ psiefit(j,k)=p(resoR*(j-1)+k,1);
184
+
185
+ end
186
+ end
187
+
188
+ %2D poloidal flux on R,Z grid
189
+ eval([fname,'.psi2D=psiefit;']);
190
+
191
+ %poloidal flux on the magnetic axis and the last-closed-flux surface
192
+ eval([fname,'.psiaxis=psiequi(1);']);
193
+ eval([fname,'.psiedge=psiequi(end);']);
194
+
195
+ %major radius
196
+ eval([fname,'.r0=rmaj;']);
197
+
198
+ %radius of the magnetic axis (difference between raxis and r0 is the Shafranov shift)
199
+ eval([fname,'.raxis=rmaxis1;']);
200
+
201
+ %z location of the geometric and magnetic axis center. If they are not the same it just means that the magnetic geometry is not up-down symmetric (which is common)
202
+ eval([fname,'.zmid=zmid;']);
203
+ eval([fname,'.zaxis=zmaxis;']);
204
+
205
+ %R and Z grids for the 2D psi
206
+ eval([fname,'.rmesh=xnodes(1,:)'';']);
207
+ eval([fname,'.zmesh=ynodes(:,1);']);
208
+
209
+ %Normalized toroidal flux coordinate grid
210
+ eval([fname,'.rhonorm=linspace(0,1,101);']);
211
+
212
+ %Toroidal flux on the last-closed-flux surface
213
+ eval([fname,'.rhoedge=rho1;']);
214
+
215
+ %1D psi on the toroidal flux grid
216
+ eval([fname,'.psi1D=psix;']);
217
+
218
+ %dvdrho on the toroidal flux grid
219
+ eval([fname,'.dvdrho=dvdrho;']);
220
+
221
+ eval(['save(''',fname,''');']);
222
+
223
+ %quick automatic contour plot of 2D flux surfaces
224
+ if printflag==1
225
+ figure; contour(xnodes,ynodes,psiefit,40); axis equal
226
+ end
@@ -0,0 +1,159 @@
1
+ function no_results = output_ogyropsi(data, tavg)
2
+
3
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4
+ % The ogyropsi CHEASE output file
5
+ % consists of MKSA quantities on a
6
+ % flux surface grid. Not sure yet
7
+ % what the spacing of the grid is
8
+ % set by.
9
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10
+
11
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12
+ % This file is currently incomplete:
13
+ % It outputs zeros for a lot of quantities
14
+ % and skips some altogether. It is intended
15
+ % to output quantities to compare to a CHEASE
16
+ % run which uses an EQDSK file from the same
17
+ % Cronos run as input
18
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19
+
20
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21
+ % data is the cronos data structure
22
+ % and t avg is an a time window given
23
+ % as an array of two values... quanitities
24
+ % are averaged over that time window.
25
+ % e.g. output_ogyropsi(data, [45.2 46]);
26
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
27
+
28
+ ind=round(interp1(data.gene.temps,1:length(data.gene.temps),tavg)); ind=ind(1):ind(2); %find the indexes in data.gene.temps of the desired time window
29
+ npsi = size(data.equi.R, 2);
30
+ nchi = size(data.equi.R, 3) - 1; % ogyropsi doesn't have the 2pi point
31
+
32
+ x=linspace(0,1,npsi);
33
+ % xrho is the values of x on the grid used for some equi quantities like psiRZ
34
+ xrho=mean(data.equi.rhoRZ(ind,:)); xrho=xrho./xrho(end); xrho=double(xrho);
35
+
36
+ outfile = fopen('ogyropsi.dat', 'w');
37
+
38
+ fprintf(outfile, 'NPSI\n %d\nNCHI\n %d\n', npsi, nchi);
39
+ R = squeeze(mean(data.equi.R(ind, :, :)));
40
+ Z = squeeze(mean(data.equi.Z(ind, :, :)));
41
+ % R and Z are not on the uniform toroidal flux grid
42
+ for i=1:(nchi+1)
43
+ R(:,i) = interp1(xrho, R(:,i), x);
44
+ Z(:,i) = interp1(xrho, Z(:,i), x);
45
+ end
46
+
47
+
48
+ B=mean(data.geo.b0(ind));
49
+ fprintf(outfile, 'R0EXP\n %16.9E\nB0EXP\n %16.9E\n', R(1,1), B);
50
+
51
+
52
+ psiequi=mean(data.equi.psiRZ(ind,:)); psiequi=(double(psiequi)); %the minus sign is there since eqdsk expects flipped psi profiles
53
+ psiequi=-psiequi + psiequi(1);
54
+ psix=interp1(xrho,psiequi,x);
55
+ %fprintf(outfile, 'PSI\n'); fprintf(outfile, form, psix);
56
+ write_array(outfile, 'PSI', psix);
57
+
58
+ chi = linspace(0.0, 2*pi, nchi+1);
59
+ chi = chi(1:nchi);
60
+ write_array(outfile, 'CHI', chi);
61
+
62
+ %%% MAJOR AND MINOR RADII
63
+ Rgeom = (R(:,1)+R(:,(nchi)/2))/2;
64
+ write_array(outfile, 'Rgeom', Rgeom);
65
+ ageom = (R(:,1)-R(:,(nchi)/2));
66
+ write_array(outfile, 'ageom', ageom);
67
+
68
+ %%% SAFETY FACTOR
69
+ q=mean(data.equi.q(ind,:)); q=double(q);
70
+ write_array(outfile, 'q', q);
71
+ dqdpsi = gradient(q, psix);
72
+ write_array(outfile, 'dqdpsi', dqdpsi);
73
+ d2qdpsi2 = gradient(dqdpsi, psix);
74
+ write_array(outfile, 'd2qdpsi2', d2qdpsi2);
75
+
76
+ %%% PRESSURE
77
+ p=mean(data.prof.ptot(ind,:));
78
+ write_array(outfile, 'p', p);
79
+ dpdpsi = gradient(p, psix);
80
+ write_array(outfile, 'dpdpsi', dpdpsi);
81
+
82
+ %%% TOROIDAL FIELD CURRENT FUNCTION
83
+ f=mean(data.equi.F(ind,:));
84
+ write_array(outfile, 'f', f);
85
+ fdfdpsi = gradient(f, psix).*f;
86
+ write_array(outfile, 'fdfdpsi', fdfdpsi);
87
+
88
+ %%% FLUX SURFACE VOLUME
89
+ v=mean(data.equi.volume(ind,:));
90
+ % The above gives NaNs.... don't know why
91
+ v = q*0.0;
92
+ write_array(outfile, 'V', v);
93
+
94
+
95
+ % SQRT TOROIDAL FLUX
96
+ rhox = interp1(xrho, mean(data.equi.rhoRZ(ind,:)), x);
97
+ write_array(outfile, 'rho_t', rhox);
98
+
99
+ %%% MAGNETIC SHEAR
100
+ shear=mean(data.equi.shear(ind,:)); shear=double(shear);
101
+ write_array(outfile, 'shear', shear);
102
+ dsheardpsi = gradient(shear, psix);
103
+ write_array(outfile, 'dsheardpsi', dsheardpsi);
104
+
105
+ dummy_array = shear*0.0;
106
+ write_array(outfile, 'kappa', dummy_array);
107
+ write_array(outfile, 'delta_lower', dummy_array);
108
+ write_array(outfile, 'delta_upper', dummy_array);
109
+ write_array(outfile, 'dVdpsi', dummy_array);
110
+ write_array(outfile, 'dpsidrhotor', dummy_array);
111
+ write_array(outfile, 'GDPSI_av', dummy_array);
112
+ write_array(outfile, 'radius_av', dummy_array);
113
+ write_array(outfile, 'R_av', dummy_array);
114
+
115
+ %%% ELECTRON PROFILES
116
+ te=mean(data.prof.te(ind,:));
117
+ write_array(outfile, 'TE', te);
118
+ dtedpsi = gradient(te, psix);
119
+ write_array(outfile, 'DTEDPSI', dtedpsi);
120
+
121
+ ne=mean(data.prof.ne(ind,:));
122
+ write_array(outfile, 'NE', ne);
123
+ dnedpsi = gradient(ne, psix);
124
+ write_array(outfile, 'DNEDPSI', dnedpsi);
125
+
126
+ %%% ION PROFILES
127
+ ti=mean(data.prof.ti(ind,:));
128
+ write_array(outfile, 'TI', ti);
129
+ dtidpsi = gradient(ti, psix);
130
+ write_array(outfile, 'DTIDPSI', dtidpsi);
131
+
132
+ ni=mean(data.prof.ni(ind,:));
133
+ write_array(outfile, 'NI', ni);
134
+ dnidpsi = gradient(ni, psix);
135
+ write_array(outfile, 'DNIDPSI', dnidpsi);
136
+
137
+ %%% ZEFF
138
+ zeff=mean(data.prof.zeff(ind,:));
139
+ write_array(outfile, 'ZEFF', zeff);
140
+
141
+ %%% MAJOR RADIUS OF FLUX SURFACES
142
+ write_array(outfile, 'R', R(:, 1:nchi));
143
+
144
+
145
+ %%% HEIGHT Z OF FLUX SURFACES
146
+ write_array(outfile, 'Z', Z(:, 1:nchi));
147
+
148
+ fclose(outfile);
149
+
150
+ function write_array(outfile, name, array)
151
+
152
+ form = ' %16.9E %16.9E %16.9E %16.9E %16.9E\n';
153
+ fprintf(outfile, '%s\n', name);
154
+ fprintf(outfile, form, array);
155
+ if mod(size(array),5) ~= 0
156
+ fprintf(outfile, '\n');
157
+ end
158
+
159
+
metadata CHANGED
@@ -1,96 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cronoscrmod
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
5
- prerelease:
4
+ version: 0.1.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Edmund Highcock
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-10-17 00:00:00.000000000 Z
11
+ date: 2017-01-16 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: coderunner
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
- version: 0.13.18
19
+ version: '1.0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: 0.13.18
26
+ version: '1.0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: shoulda
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
- version: '0'
33
+ version: '3.5'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
- version: '0'
40
+ version: '3.5'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rdoc
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ~>
45
+ - - "~>"
52
46
  - !ruby/object:Gem::Version
53
47
  version: '3.12'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ~>
52
+ - - "~>"
60
53
  - !ruby/object:Gem::Version
61
54
  version: '3.12'
62
- - !ruby/object:Gem::Dependency
63
- name: bundler
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ! '>'
68
- - !ruby/object:Gem::Version
69
- version: 1.0.0
70
- type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ! '>'
76
- - !ruby/object:Gem::Version
77
- version: 1.0.0
78
55
  - !ruby/object:Gem::Dependency
79
56
  name: jeweler
80
57
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
58
  requirements:
83
- - - ! '>='
59
+ - - "~>"
84
60
  - !ruby/object:Gem::Version
85
- version: 1.8.4
61
+ version: '2.3'
86
62
  type: :development
87
63
  prerelease: false
88
64
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
65
  requirements:
91
- - - ! '>='
66
+ - - "~>"
92
67
  - !ruby/object:Gem::Version
93
- version: 1.8.4
68
+ version: '2.3'
94
69
  description: A module to allow CodeRunner to run the integrated tokamak modelling
95
70
  suite Cronos. Requires matlab and matlab-ruby (Cronos also requires Matlab).
96
71
  email: edmundhighcock@users.sourceforge.net
@@ -102,10 +77,11 @@ extra_rdoc_files:
102
77
  - README.md.orig
103
78
  - README.rdoc
104
79
  files:
105
- - .document
80
+ - ".document"
106
81
  - Gemfile
107
82
  - LICENSE.txt
108
83
  - README.md
84
+ - README.md.orig
109
85
  - README.rdoc
110
86
  - Rakefile
111
87
  - VERSION
@@ -113,36 +89,34 @@ files:
113
89
  - lib/cronoscrmod.rb
114
90
  - lib/cronoscrmod/cronos.rb
115
91
  - lib/cronoscrmod/defaults_files/cronos_defaults.rb
92
+ - lib/cronoscrmod/matlab/cronos_eqdsk.m
93
+ - lib/cronoscrmod/matlab/eqdsk_jc.m
94
+ - lib/cronoscrmod/matlab/output_ogyropsi.m
116
95
  - test/helper.rb
117
96
  - test/test_cronoscrmod.rb
118
- - README.md.orig
119
97
  homepage: http://github.com/edmundhighcock/cronoscrmod
120
98
  licenses:
121
99
  - MIT
100
+ metadata: {}
122
101
  post_install_message:
123
102
  rdoc_options: []
124
103
  require_paths:
125
104
  - lib
126
105
  required_ruby_version: !ruby/object:Gem::Requirement
127
- none: false
128
106
  requirements:
129
- - - ! '>='
107
+ - - ">="
130
108
  - !ruby/object:Gem::Version
131
109
  version: '0'
132
- segments:
133
- - 0
134
- hash: 2607351872289710569
135
110
  required_rubygems_version: !ruby/object:Gem::Requirement
136
- none: false
137
111
  requirements:
138
- - - ! '>='
112
+ - - ">="
139
113
  - !ruby/object:Gem::Version
140
114
  version: '0'
141
115
  requirements: []
142
116
  rubyforge_project:
143
- rubygems_version: 1.8.23
117
+ rubygems_version: 2.6.8
144
118
  signing_key:
145
- specification_version: 3
119
+ specification_version: 4
146
120
  summary: A module to allow CodeRunner to run the integrated tokamak modelling suite
147
121
  Cronos
148
122
  test_files: []