cronoscrmod 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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: []