fargopy 0.2.0__py3-none-any.whl → 0.3.0__py3-none-any.whl
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.
- fargopy/__init__.py +202 -87
- fargopy/fields.py +221 -0
- fargopy/simulation.py +845 -0
- fargopy/sys.py +41 -18
- fargopy/util.py +4 -0
- fargopy/version.py +1 -1
- {fargopy-0.2.0.dist-info → fargopy-0.3.0.dist-info}/LICENSE +0 -0
- fargopy-0.3.0.dist-info/METADATA +243 -0
- fargopy-0.3.0.dist-info/RECORD +13 -0
- {fargopy-0.2.0.dist-info → fargopy-0.3.0.dist-info}/WHEEL +1 -1
- fargopy/__cycle1.py +0 -880
- fargopy/conf.py +0 -20
- fargopy/fargo3d.py +0 -505
- fargopy-0.2.0.dist-info/METADATA +0 -470
- fargopy-0.2.0.dist-info/RECORD +0 -14
- {fargopy-0.2.0.data → fargopy-0.3.0.data}/scripts/ifargopy +0 -0
- {fargopy-0.2.0.dist-info → fargopy-0.3.0.dist-info}/entry_points.txt +0 -0
- {fargopy-0.2.0.dist-info → fargopy-0.3.0.dist-info}/top_level.txt +0 -0
fargopy/__init__.py
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
###############################################################
|
|
2
|
-
#
|
|
2
|
+
# Version
|
|
3
3
|
###############################################################
|
|
4
4
|
from fargopy.version import *
|
|
5
|
-
from fargopy.util import *
|
|
6
|
-
from fargopy.sys import *
|
|
7
|
-
from fargopy.fargo3d import *
|
|
8
5
|
|
|
9
6
|
###############################################################
|
|
10
7
|
# External modules
|
|
@@ -23,88 +20,59 @@ import numpy as np
|
|
|
23
20
|
DEG = np.pi/180
|
|
24
21
|
RAD = 1/DEG
|
|
25
22
|
|
|
26
|
-
FP_HOME = os.environ['HOME']
|
|
27
|
-
FP_DOTDIR = f"{FP_HOME}/.fargopy"
|
|
28
|
-
FP_RCFILE = f"{FP_DOTDIR}/fargopyrc"
|
|
29
|
-
|
|
30
|
-
# Default configuration
|
|
31
|
-
FP_CONFIGURATION = f"""# This is the configuration variables for FARGOpy
|
|
32
|
-
# Package
|
|
33
|
-
FP_VERSION = '{version}'
|
|
34
|
-
# System
|
|
35
|
-
FP_HOME = '{FP_HOME}'
|
|
36
|
-
# Directories
|
|
37
|
-
FP_DOTDIR = '{FP_DOTDIR}'
|
|
38
|
-
FP_RCFILE = '{FP_RCFILE}'
|
|
39
|
-
# Behavior
|
|
40
|
-
FP_VERBOSE = False
|
|
41
|
-
# FARGO3D variablles
|
|
42
|
-
FP_FARGO3D_CLONECMD = 'git clone https://bitbucket.org/fargo3d/public.git'
|
|
43
|
-
FP_FARGO3D_BASEDIR = './'
|
|
44
|
-
FP_FARGO3D_PACKDIR = 'fargo3d/'
|
|
45
|
-
FP_FARGO3D_BINARY = 'fargo3d'
|
|
46
|
-
FP_FARGO3D_HEADER = 'src/fargo3d.h'
|
|
47
|
-
"""
|
|
48
|
-
|
|
49
|
-
FP_INITIAL_SCRIPT = """
|
|
50
|
-
import sys
|
|
51
|
-
import fargopy as fp
|
|
52
|
-
fp.initialize(' '.join(sys.argv))
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
23
|
###############################################################
|
|
56
|
-
# Base
|
|
24
|
+
# Base classes
|
|
57
25
|
###############################################################
|
|
58
26
|
class Debug(object):
|
|
27
|
+
"""The Debug class control the Debugging messages of the package.
|
|
28
|
+
|
|
29
|
+
Attribute:
|
|
30
|
+
VERBOSE: bool, default = False:
|
|
31
|
+
If True all the trace messages are shown.
|
|
32
|
+
|
|
33
|
+
Static methods:
|
|
34
|
+
trace(msg):
|
|
35
|
+
Show a debugging message if VERBOSE=True
|
|
36
|
+
Example:
|
|
37
|
+
>>> import fargopy as fp
|
|
38
|
+
>>> fp.Debug.VERBOSE = True
|
|
39
|
+
>>> fp.initialize('configure')
|
|
40
|
+
"""
|
|
59
41
|
VERBOSE = False
|
|
60
42
|
@staticmethod
|
|
61
43
|
def trace(msg):
|
|
62
44
|
if Debug.VERBOSE:
|
|
63
45
|
print("::"+msg)
|
|
64
46
|
|
|
65
|
-
def initialize(options='', force=False):
|
|
66
|
-
if ('configure' in options) or ('all' in options):
|
|
67
|
-
# Create configuration directory
|
|
68
|
-
if not os.path.isdir(FP_DOTDIR) or force:
|
|
69
|
-
Debug.trace(f"Configuring FARGOpy...")
|
|
70
|
-
# Create directory
|
|
71
|
-
os.system(f"mkdir -p {FP_DOTDIR}")
|
|
72
|
-
# Create configuration variables
|
|
73
|
-
f = open(f"{FP_DOTDIR}/fargopyrc",'w')
|
|
74
|
-
f.write(FP_CONFIGURATION)
|
|
75
|
-
f.close()
|
|
76
|
-
# Create initialization script
|
|
77
|
-
f = open(f"{FP_DOTDIR}/ifargopy.py",'w')
|
|
78
|
-
f.write(FP_INITIAL_SCRIPT)
|
|
79
|
-
f.close()
|
|
80
|
-
|
|
81
|
-
if ('download' in options) or ('all' in options):
|
|
82
|
-
print("Downloading FARGOpy...")
|
|
83
|
-
fargo_dir = f"{FP_FARGO3D_BASEDIR}/{FP_FARGO3D_PACKDIR}".replace('//','/')
|
|
84
|
-
if not os.path.isdir(fargo_dir):
|
|
85
|
-
fargopy.Sys.simple(f"{FP_FARGO3D_CLONECMD} {FP_FARGO3D_PACKDIR}")
|
|
86
|
-
print(f"\tFARGO3D downloaded to {fargo_dir}")
|
|
87
|
-
else:
|
|
88
|
-
print(f"\tFARGO3D directory already present in '{fargo_dir}'")
|
|
89
|
-
|
|
90
|
-
fargo_header = f"{fargo_dir}/{FP_FARGO3D_HEADER}"
|
|
91
|
-
if not os.path.isfile(fargo_header):
|
|
92
|
-
print(f"No header file for fargo found in '{fargo_header}'")
|
|
93
|
-
|
|
94
|
-
if ('compile' in options) or ('all' in options):
|
|
95
|
-
print("Test compilation")
|
|
96
|
-
pass
|
|
97
|
-
|
|
98
47
|
class Dictobj(object):
|
|
99
48
|
"""Convert a dictionary to an object
|
|
100
49
|
|
|
50
|
+
Initialization attributes:
|
|
51
|
+
dict: dictionary:
|
|
52
|
+
Dictionary containing the attributes.
|
|
53
|
+
|
|
54
|
+
Attributes:
|
|
55
|
+
All the keys in the initialization dictionary.
|
|
56
|
+
|
|
101
57
|
Examples:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
ob = Dictobj(dict=dict(a=2,b=3))
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
58
|
+
Three ways to initialize the same `Dictobj`:
|
|
59
|
+
>>> ob = Dictobj(a=2,b=3)
|
|
60
|
+
>>> ob = Dictobj(dict=dict(a=2,b=3))
|
|
61
|
+
>>> ob = Dictobj(dict={'a':2,'b':3})
|
|
62
|
+
|
|
63
|
+
In the three cases you may access the attributes using:
|
|
64
|
+
>>> print(ob.a,ob.b)
|
|
65
|
+
|
|
66
|
+
Methods:
|
|
67
|
+
keys():
|
|
68
|
+
It works like the keys() method of a dictionary.
|
|
69
|
+
item(key):
|
|
70
|
+
Recover the value of an attribute as it was a dictionary.
|
|
71
|
+
Example:
|
|
72
|
+
>>> ob.item('a')
|
|
73
|
+
print_keys():
|
|
74
|
+
Print a list of keys
|
|
75
|
+
|
|
108
76
|
"""
|
|
109
77
|
|
|
110
78
|
def __init__(self, **kwargs):
|
|
@@ -115,6 +83,10 @@ class Dictobj(object):
|
|
|
115
83
|
setattr(self, key, value)
|
|
116
84
|
|
|
117
85
|
def keys(self):
|
|
86
|
+
"""Show the list of attributes of Dictobj
|
|
87
|
+
|
|
88
|
+
This method works as the keys() method of a regular dictionary.
|
|
89
|
+
"""
|
|
118
90
|
props = []
|
|
119
91
|
for i,prop in enumerate(self.__dict__.keys()):
|
|
120
92
|
if '__' in prop:
|
|
@@ -122,7 +94,16 @@ class Dictobj(object):
|
|
|
122
94
|
props += [prop]
|
|
123
95
|
return props
|
|
124
96
|
|
|
97
|
+
def item(self,key):
|
|
98
|
+
"""Get the value of an item of a Dictobj.
|
|
99
|
+
"""
|
|
100
|
+
if key not in self.keys():
|
|
101
|
+
raise ValueError(f"Key 'key' not in Dictobj")
|
|
102
|
+
return self.__dict__[key]
|
|
103
|
+
|
|
125
104
|
def print_keys(self):
|
|
105
|
+
"""Print all the keys of a Dictobj.
|
|
106
|
+
"""
|
|
126
107
|
prop_list=''
|
|
127
108
|
for i,prop in enumerate(self.keys()):
|
|
128
109
|
prop_list += f"{prop}, "
|
|
@@ -130,17 +111,135 @@ class Dictobj(object):
|
|
|
130
111
|
prop_list += '\n'
|
|
131
112
|
print(prop_list.strip(', '))
|
|
132
113
|
|
|
133
|
-
def item(self,key):
|
|
134
|
-
if key not in self.keys():
|
|
135
|
-
raise ValueError(f"Key 'key' not in Dictobj")
|
|
136
|
-
return self.__dict__[key]
|
|
137
|
-
|
|
138
114
|
def __str__(self):
|
|
139
115
|
return str(self.__dict__)
|
|
140
116
|
|
|
141
117
|
def __repr__(self):
|
|
142
118
|
return self.__str__()
|
|
143
119
|
|
|
120
|
+
class Fargobj(object):
|
|
121
|
+
def __init__(self,**kwargs):
|
|
122
|
+
self.fobject = True
|
|
123
|
+
self.kwargs = kwargs
|
|
124
|
+
|
|
125
|
+
def set_property(self,property,default,method=lambda prop:prop):
|
|
126
|
+
"""Set a property of object using a given method
|
|
127
|
+
|
|
128
|
+
Examples:
|
|
129
|
+
>>> obj = Fargobj()
|
|
130
|
+
>>> obj.set_property('a',1)
|
|
131
|
+
>>> print(obj.a)
|
|
132
|
+
1
|
|
133
|
+
"""
|
|
134
|
+
if property in self.kwargs.keys():
|
|
135
|
+
method(self.kwargs[property])
|
|
136
|
+
self.__dict__[property] = self.kwargs[property]
|
|
137
|
+
return True
|
|
138
|
+
else:
|
|
139
|
+
method(default)
|
|
140
|
+
self.__dict__[property] = default
|
|
141
|
+
return False
|
|
142
|
+
|
|
143
|
+
def has(self,key):
|
|
144
|
+
"""Check if a key is an attribute of Fargobj object
|
|
145
|
+
|
|
146
|
+
Examples:
|
|
147
|
+
>>> obj = Fargobj(a=1)
|
|
148
|
+
>>> print(obj.has('a'))
|
|
149
|
+
True
|
|
150
|
+
"""
|
|
151
|
+
if key in self.__dict__.keys():
|
|
152
|
+
return True
|
|
153
|
+
else:
|
|
154
|
+
return False
|
|
155
|
+
|
|
156
|
+
###############################################################
|
|
157
|
+
# Package configuration
|
|
158
|
+
###############################################################
|
|
159
|
+
# Basic (unmodifiable) variables
|
|
160
|
+
Conf = Dictobj()
|
|
161
|
+
Conf.FP_HOME = os.environ['HOME']
|
|
162
|
+
Conf.FP_DOTDIR = f"{Conf.FP_HOME}/.fargopy"
|
|
163
|
+
Conf.FP_RCFILE = f"{Conf.FP_DOTDIR}/fargopyrc"
|
|
164
|
+
|
|
165
|
+
# Default configuration file content
|
|
166
|
+
Conf.FP_CONFIGURATION = f"""# This is the configuration variables for FARGOpy
|
|
167
|
+
# Package
|
|
168
|
+
FP_VERSION = '{version}'
|
|
169
|
+
# System
|
|
170
|
+
FP_HOME = '{Conf.FP_HOME}/'
|
|
171
|
+
# Directories
|
|
172
|
+
FP_DOTDIR = '{Conf.FP_DOTDIR}'
|
|
173
|
+
FP_RCFILE = '{Conf.FP_RCFILE}'
|
|
174
|
+
# Behavior
|
|
175
|
+
FP_VERBOSE = False
|
|
176
|
+
# FARGO3D variablles
|
|
177
|
+
FP_FARGO3D_CLONECMD = 'git clone https://bitbucket.org/fargo3d/public.git'
|
|
178
|
+
FP_FARGO3D_BASEDIR = '{Conf.FP_HOME}'
|
|
179
|
+
FP_FARGO3D_PACKDIR = 'fargo3d/'
|
|
180
|
+
FP_FARGO3D_BINARY = 'fargo3d'
|
|
181
|
+
FP_FARGO3D_HEADER = 'src/fargo3d.h'
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
# Default initialization script
|
|
185
|
+
Conf.FP_INITIAL_SCRIPT = """
|
|
186
|
+
import sys
|
|
187
|
+
import fargopy as fp
|
|
188
|
+
fp.initialize(' '.join(sys.argv))
|
|
189
|
+
"""
|
|
190
|
+
|
|
191
|
+
def initialize(options='', force=False):
|
|
192
|
+
"""Initialization routine
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
options: string, default = '':
|
|
196
|
+
Action(s) to be performed. Valid actions include:
|
|
197
|
+
'configure': configure the package.
|
|
198
|
+
'download': download FARGO3D directory.
|
|
199
|
+
'compile': attempt to compile FARGO3D in the machine.
|
|
200
|
+
'all': all actions.
|
|
201
|
+
|
|
202
|
+
force: bool, default = False:
|
|
203
|
+
If True, force any action that depends on a previous condition.
|
|
204
|
+
For instance if options = 'configure' and force = True it will
|
|
205
|
+
override FARGOpy directory.
|
|
206
|
+
"""
|
|
207
|
+
if ('configure' in options) or ('all' in options):
|
|
208
|
+
# Create configuration directory
|
|
209
|
+
if not os.path.isdir(Conf.FP_DOTDIR) or force:
|
|
210
|
+
Debug.trace(f"Configuring FARGOpy at {Conf.FP_DOTDIR}...")
|
|
211
|
+
# Create directory
|
|
212
|
+
os.system(f"mkdir -p {Conf.FP_DOTDIR}")
|
|
213
|
+
# Create configuration variables
|
|
214
|
+
f = open(f"{Conf.FP_DOTDIR}/fargopyrc",'w')
|
|
215
|
+
f.write(Conf.FP_CONFIGURATION)
|
|
216
|
+
f.close()
|
|
217
|
+
# Create initialization script
|
|
218
|
+
f = open(f"{Conf.FP_DOTDIR}/ifargopy.py",'w')
|
|
219
|
+
f.write(Conf.FP_INITIAL_SCRIPT)
|
|
220
|
+
f.close()
|
|
221
|
+
else:
|
|
222
|
+
Debug.trace(f"Configuration already in place.")
|
|
223
|
+
|
|
224
|
+
if ('download' in options) or ('all' in options):
|
|
225
|
+
print("Downloading FARGOpy...")
|
|
226
|
+
fargo_dir = f"{Conf.FP_FARGO3D_BASEDIR}/{Conf.FP_FARGO3D_PACKDIR}".replace('//','/')
|
|
227
|
+
if not os.path.isdir(fargo_dir) or force:
|
|
228
|
+
fargopy.Sys.simple(f"cd {Conf.FP_FARGO3D_BASEDIR};{Conf.FP_FARGO3D_CLONECMD} {Conf.FP_FARGO3D_PACKDIR}")
|
|
229
|
+
print(f"\tFARGO3D downloaded to {fargo_dir}")
|
|
230
|
+
else:
|
|
231
|
+
print(f"\tFARGO3D directory already present in '{fargo_dir}'")
|
|
232
|
+
|
|
233
|
+
fargo_header = f"{fargo_dir}/{Conf.FP_FARGO3D_HEADER}"
|
|
234
|
+
if not os.path.isfile(fargo_header):
|
|
235
|
+
print(f"No header file for fargo found in '{fargo_header}'")
|
|
236
|
+
else:
|
|
237
|
+
print(f"Header file for FARGO3D is in the fargo directory {fargo_dir}")
|
|
238
|
+
|
|
239
|
+
if ('compile' in options) or ('all' in options):
|
|
240
|
+
print("Test compilation")
|
|
241
|
+
pass
|
|
242
|
+
|
|
144
243
|
###############################################################
|
|
145
244
|
# Initialization
|
|
146
245
|
###############################################################
|
|
@@ -148,23 +247,39 @@ class Dictobj(object):
|
|
|
148
247
|
warnings.filterwarnings("ignore")
|
|
149
248
|
|
|
150
249
|
# Read FARGOpy configuration variables
|
|
151
|
-
if not os.path.isdir(FP_DOTDIR):
|
|
152
|
-
|
|
250
|
+
if not os.path.isdir(Conf.FP_DOTDIR):
|
|
251
|
+
print(f"Configuring FARGOpy for the first time")
|
|
153
252
|
initialize('configure')
|
|
154
253
|
Debug.trace(f"::Reading configuration variables")
|
|
155
|
-
|
|
156
|
-
|
|
254
|
+
|
|
255
|
+
# Load configuration variables into Conf
|
|
256
|
+
conf_dict = dict()
|
|
257
|
+
exec(open(f"{Conf.FP_RCFILE}").read(),dict(),conf_dict)
|
|
258
|
+
Conf.__dict__.update(conf_dict)
|
|
259
|
+
|
|
260
|
+
# Derivative configuration variables
|
|
261
|
+
Debug.VERBOSE = Conf.FP_VERBOSE
|
|
262
|
+
Conf.FP_FARGO3D_DIR = (Conf.FP_FARGO3D_BASEDIR + '/' + Conf.FP_FARGO3D_PACKDIR).replace('//','/')
|
|
263
|
+
Conf.FP_FARGO3D_LOCKFILE = f"{Conf.FP_DOTDIR}/fargopy.lock"
|
|
157
264
|
|
|
158
265
|
# Check if version in RCFILE is different from installed FARGOpy version
|
|
159
|
-
if FP_VERSION != version:
|
|
160
|
-
print(f"Your
|
|
161
|
-
ans = input(f"Do you want to update configuration file '{FP_RCFILE}'? [Y/n]: ")
|
|
266
|
+
if Conf.FP_VERSION != version:
|
|
267
|
+
print(f"Your configuration file version '{Conf.FP_VERSION}' it is different than the installed version of FARGOpy '{version}'")
|
|
268
|
+
ans = input(f"Do you want to update configuration file '{Conf.FP_RCFILE}'? [Y/n]: ")
|
|
162
269
|
if ans and ('Y' not in ans.upper()):
|
|
163
270
|
if 'N' in ans.upper():
|
|
164
|
-
print("We will keeping asking you until you update it, sorry!")
|
|
271
|
+
print("We will keeping asking you this until you update it, sorry!")
|
|
165
272
|
else:
|
|
166
|
-
os.system(f"cp -rf {FP_RCFILE} {FP_RCFILE}.save")
|
|
273
|
+
os.system(f"cp -rf {Conf.FP_RCFILE} {Conf.FP_RCFILE}.save")
|
|
167
274
|
initialize('configure',force=True)
|
|
168
275
|
|
|
276
|
+
###############################################################
|
|
277
|
+
# Import package modules
|
|
278
|
+
###############################################################
|
|
279
|
+
from fargopy.util import *
|
|
280
|
+
from fargopy.sys import *
|
|
281
|
+
from fargopy.fields import *
|
|
282
|
+
from fargopy.simulation import *
|
|
283
|
+
|
|
169
284
|
# Showing version
|
|
170
285
|
print(f"Running FARGOpy version {version}")
|
fargopy/fields.py
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
###############################################################
|
|
2
|
+
# FARGOpy interdependencies
|
|
3
|
+
###############################################################
|
|
4
|
+
import fargopy
|
|
5
|
+
|
|
6
|
+
###############################################################
|
|
7
|
+
# Required packages
|
|
8
|
+
###############################################################
|
|
9
|
+
import numpy as np
|
|
10
|
+
import re
|
|
11
|
+
|
|
12
|
+
###############################################################
|
|
13
|
+
# Constants
|
|
14
|
+
###############################################################
|
|
15
|
+
# Map of coordinates into FARGO3D coordinates
|
|
16
|
+
COORDS_MAP = dict(
|
|
17
|
+
cartesian = dict(x='x',y='y',z='z'),
|
|
18
|
+
cylindrical = dict(phi='x',r='y',z='z'),
|
|
19
|
+
spherical = dict(phi='x',r='y',theta='z'),
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
###############################################################
|
|
23
|
+
# Classes
|
|
24
|
+
###############################################################
|
|
25
|
+
class Field(fargopy.Fargobj):
|
|
26
|
+
"""Fields:
|
|
27
|
+
|
|
28
|
+
Attributes:
|
|
29
|
+
coordinates: type of coordinates (cartesian, cylindrical, spherical)
|
|
30
|
+
data: numpy arrays with data of the field
|
|
31
|
+
|
|
32
|
+
Methods:
|
|
33
|
+
slice: get an slice of a field along a given spatial direction.
|
|
34
|
+
Examples:
|
|
35
|
+
density.slice(r=0.5) # Take the closest slice to r = 0.5
|
|
36
|
+
density.slice(ir=20) # Take the slice through the 20 shell
|
|
37
|
+
density.slice(phi=30*RAD,interp='nearest') # Take a slice interpolating to the nearest
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(self,data=None,coordinates='cartesian',domains=None,type='scalar',**kwargs):
|
|
41
|
+
super().__init__(**kwargs)
|
|
42
|
+
self.data = data
|
|
43
|
+
self.coordinates = coordinates
|
|
44
|
+
self.domains = domains
|
|
45
|
+
self.type = type
|
|
46
|
+
|
|
47
|
+
def meshslice(self,slice=None,component=0):
|
|
48
|
+
"""Perform a slice on a field and produce as an output the
|
|
49
|
+
corresponding field slice and the associated matrices of
|
|
50
|
+
coordinates for plotting.
|
|
51
|
+
"""
|
|
52
|
+
# Analysis of the slice
|
|
53
|
+
if slice is None:
|
|
54
|
+
raise ValueError("You must provide a slice option.")
|
|
55
|
+
|
|
56
|
+
# Perform the slice
|
|
57
|
+
slice_cmd = f"self.slice({slice},pattern=True)"
|
|
58
|
+
slice,pattern = eval(slice_cmd)
|
|
59
|
+
|
|
60
|
+
# Create the mesh
|
|
61
|
+
if self.coordinates == 'cartesian':
|
|
62
|
+
z,y,x = np.meshgrid(self.domains.z,self.domains.y,self.domains.x,indexing='ij')
|
|
63
|
+
x = eval(f"x[{pattern}]")
|
|
64
|
+
y = eval(f"y[{pattern}]")
|
|
65
|
+
z = eval(f"z[{pattern}]")
|
|
66
|
+
|
|
67
|
+
mesh = fargopy.Dictobj(dict=dict(x=x,y=y,z=z))
|
|
68
|
+
|
|
69
|
+
if self.coordinates == 'cylindrical':
|
|
70
|
+
z,r,phi = np.meshgrid(self.domains.z,self.domains.r,self.domains.phi,indexing='ij')
|
|
71
|
+
x,y,z = r*np.cos(phi),r*np.sin(phi),z
|
|
72
|
+
|
|
73
|
+
x = eval(f"x[{pattern}]")
|
|
74
|
+
y = eval(f"y[{pattern}]")
|
|
75
|
+
z = eval(f"z[{pattern}]")
|
|
76
|
+
r = eval(f"r[{pattern}]")
|
|
77
|
+
phi = eval(f"phi[{pattern}]")
|
|
78
|
+
|
|
79
|
+
mesh = fargopy.Dictobj(dict=dict(r=r,phi=phi,x=x,y=y,z=z))
|
|
80
|
+
|
|
81
|
+
if self.coordinates == 'spherical':
|
|
82
|
+
theta,r,phi = np.meshgrid(self.domains.theta,self.domains.r,self.domains.phi,indexing='ij')
|
|
83
|
+
x,y,z = r*np.sin(theta)*np.cos(phi),r*np.sin(theta)*np.sin(phi),r*np.cos(theta)
|
|
84
|
+
|
|
85
|
+
x = eval(f"x[{pattern}]")
|
|
86
|
+
y = eval(f"y[{pattern}]")
|
|
87
|
+
z = eval(f"z[{pattern}]")
|
|
88
|
+
r = eval(f"r[{pattern}]")
|
|
89
|
+
phi = eval(f"phi[{pattern}]")
|
|
90
|
+
theta = eval(f"theta[{pattern}]")
|
|
91
|
+
|
|
92
|
+
mesh = fargopy.Dictobj(dict=dict(r=r,phi=phi,theta=theta,x=x,y=y,z=z))
|
|
93
|
+
|
|
94
|
+
return slice,mesh
|
|
95
|
+
|
|
96
|
+
def slice(self,quiet=True,pattern=False,**kwargs):
|
|
97
|
+
"""Extract an slice of a 3-dimensional FARGO3D field
|
|
98
|
+
|
|
99
|
+
Parameters:
|
|
100
|
+
quiet: boolean, default = False:
|
|
101
|
+
If True extract the slice quietly.
|
|
102
|
+
Else, print some control messages.
|
|
103
|
+
|
|
104
|
+
pattern: boolean, default = False:
|
|
105
|
+
If True return the pattern of the slice, eg. [:,:,:]
|
|
106
|
+
|
|
107
|
+
ir, iphi, itheta, ix, iy, iz: string or integer:
|
|
108
|
+
Index or range of indexes of the corresponding coordinate.
|
|
109
|
+
|
|
110
|
+
r, phi, theta, x, y, z: float:
|
|
111
|
+
Value for slicing. The slicing search for the closest
|
|
112
|
+
value in the domain.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
slice: sliced field.
|
|
116
|
+
|
|
117
|
+
Examples:
|
|
118
|
+
# 0D: Get the value of the field in iphi = 0, itheta = -1 and close to r = 0.82
|
|
119
|
+
gasvz.slice(iphi=0,itheta=-1,r=0.82)
|
|
120
|
+
|
|
121
|
+
# 1D: Get all values of the field in radial direction at iphi = 0, itheta = -1
|
|
122
|
+
gasvz.slice(iphi=0,itheta=-1)
|
|
123
|
+
|
|
124
|
+
# 2D: Get all values of the field for values close to phi = 0
|
|
125
|
+
gasvz.slice(phi=0)
|
|
126
|
+
"""
|
|
127
|
+
# By default slice
|
|
128
|
+
ivar = dict(x=':',y=':',z=':')
|
|
129
|
+
|
|
130
|
+
if len(kwargs.keys()) == 0:
|
|
131
|
+
pattern_str = f"{ivar['z']},{ivar['y']},{ivar['x']}"
|
|
132
|
+
if pattern:
|
|
133
|
+
return self.data, pattern_str
|
|
134
|
+
return self.data
|
|
135
|
+
|
|
136
|
+
# Check all conditions
|
|
137
|
+
for key,item in kwargs.items():
|
|
138
|
+
match = re.match('^i(.+)',key)
|
|
139
|
+
if match:
|
|
140
|
+
index = item
|
|
141
|
+
coord = match.group(1)
|
|
142
|
+
if not quiet:
|
|
143
|
+
print(f"Index condition {index} for coordinate {coord}")
|
|
144
|
+
ivar[COORDS_MAP[self.coordinates][coord]] = index
|
|
145
|
+
else:
|
|
146
|
+
if not quiet:
|
|
147
|
+
print(f"Numeric condition found for coordinate {key}")
|
|
148
|
+
if key in self.domains.keys():
|
|
149
|
+
# Check if value provided is in range
|
|
150
|
+
domain = self.domains.item(key)
|
|
151
|
+
extrema = self.domains.extrema[key]
|
|
152
|
+
min, max = extrema[0][1], extrema[1][1]
|
|
153
|
+
if (item<min) or (item>max):
|
|
154
|
+
raise ValueError(f"You are attempting to get a slice in {key} = {item}, but the valid range for this variable is [{min},{max}]")
|
|
155
|
+
find = abs(self.domains.item(key) - item)
|
|
156
|
+
ivar[COORDS_MAP[self.coordinates][key]] = find.argmin()
|
|
157
|
+
|
|
158
|
+
pattern_str = f"{ivar['z']},{ivar['y']},{ivar['x']}"
|
|
159
|
+
|
|
160
|
+
if self.type == 'scalar':
|
|
161
|
+
slice_cmd = f"self.data[{pattern_str}]"
|
|
162
|
+
if not quiet:
|
|
163
|
+
print(f"Slice: {slice_cmd}")
|
|
164
|
+
slice = eval(slice_cmd)
|
|
165
|
+
|
|
166
|
+
elif self.type == 'vector':
|
|
167
|
+
slice = np.array(
|
|
168
|
+
[eval(f"self.data[0,{pattern_str}]"),
|
|
169
|
+
eval(f"self.data[1,{pattern_str}]"),
|
|
170
|
+
eval(f"self.data[2,{pattern_str}]")]
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
if pattern:
|
|
174
|
+
return slice,pattern_str
|
|
175
|
+
return slice
|
|
176
|
+
|
|
177
|
+
def to_cartesian(self):
|
|
178
|
+
if self.type == 'scalar':
|
|
179
|
+
# Scalar fields are invariant under coordinate transformations
|
|
180
|
+
return self
|
|
181
|
+
elif self.type == 'vector':
|
|
182
|
+
# Vector fields must be transformed according to domain
|
|
183
|
+
if self.coordinates == 'cartesian':
|
|
184
|
+
return self
|
|
185
|
+
|
|
186
|
+
if self.coordinates == 'cylindrical':
|
|
187
|
+
z,r,phi = np.meshgrid(self.domains.z,self.domains.r,self.domains.phi,indexing='ij')
|
|
188
|
+
vphi = self.data[0]
|
|
189
|
+
vr = self.data[1]
|
|
190
|
+
vz = self.data[2]
|
|
191
|
+
vx = vr*np.cos(phi)
|
|
192
|
+
vy = vr*np.sin(phi)
|
|
193
|
+
|
|
194
|
+
return (Field(vx,coordinates=self.coordinates,domains=self.domains,type='scalar'),
|
|
195
|
+
Field(vy,coordinates=self.coordinates,domains=self.domains,type='scalar'),
|
|
196
|
+
Field(vz,coordinates=self.coordinates,domains=self.domains,type='scalar'))
|
|
197
|
+
|
|
198
|
+
if self.coordinates == 'spherical':
|
|
199
|
+
|
|
200
|
+
theta,r,phi = np.meshgrid(self.domains.theta,self.domains.r,self.domains.phi,indexing='ij')
|
|
201
|
+
vphi = self.data[0]
|
|
202
|
+
vr = self.data[1]
|
|
203
|
+
vtheta = self.data[2]
|
|
204
|
+
|
|
205
|
+
vx = vr*np.sin(theta)*np.cos(phi) + vtheta*np.cos(theta)*np.cos(phi) - vphi*np.sin(phi)
|
|
206
|
+
vy = vr*np.sin(theta)*np.sin(phi) + vtheta*np.cos(theta)*np.sin(phi) + vphi*np.cos(phi)
|
|
207
|
+
vz = vr*np.cos(theta) - vtheta*np.sin(theta)
|
|
208
|
+
|
|
209
|
+
return (Field(vx,coordinates=self.coordinates,domains=self.domains,type='scalar'),
|
|
210
|
+
Field(vy,coordinates=self.coordinates,domains=self.domains,type='scalar'),
|
|
211
|
+
Field(vz,coordinates=self.coordinates,domains=self.domains,type='scalar'))
|
|
212
|
+
|
|
213
|
+
def get_size(self):
|
|
214
|
+
return self.data.nbytes/1024**2
|
|
215
|
+
|
|
216
|
+
def __str__(self):
|
|
217
|
+
return str(self.data)
|
|
218
|
+
|
|
219
|
+
def __repr__(self):
|
|
220
|
+
return str(self.data)
|
|
221
|
+
|