User Manual: Code: World.pm
From FLUX
(back to the User Manual or the code section)
World.pm (and its associated XS file, World.xs) implements the Flux::World object. It consists mostly of methods that act directly on the world as a whole. The main constructors are str2world and read_world, each of which constructs a new struct WORLD using the code in io.c.
Flux::World objects are tied hash refs, so you can read and manipulate all of the data fields in the underlying WORLD struct via hash keys in Perl. There are also several access methods that can be used to manipulate some of the fields in the World, left over from the time before the hash ref interface was written.
Contents |
Hash structure
You can access the hash fields in a Flux::World in the usual way, for example:
use Flux;
$a = read_world('/usr/local/src/flux/pdl/menagerie/potential.flux');
print $a->{refct}; # Retrieve a simple field
@forces = @{$a->{forces}}; # Retrieve a list field
$a->{dtau} = 0.1; # Set a simple field
print keys %$a; # Display all the possible keys
Because the hash is not a true Perl hash but rather is tied to an underlying C structure, you can't set any keys that aren't part of the predefined set -- they are silently dropped on the floor. Likewise, retrieving any other key than the predefined set will return undef.
Many of the fields are used to control aspects of the simulation; some are dangerous to manipulate, and are noted. Some of the fields (mostly the ones that return other Flux::<foo> objects) are read-only. The returned objects can themselves be treated as hashes and manipulated, but to preserve the integrity of the data structure they can't be assigned to directly. For that (e.g. to add a new fluxon or to force a fluxon to terminate at a different flux concentration) you must use higher level manipulation methods.
| Key | Type | RW? | Description |
| frame_number | int | rw | Used to keep track of time step in a time-dependent simulation (see also rel_step, below).
|
| state | int | rw | Unused (but reserved) |
| concentrations | Flux::Concentration | ro | Holds the top of a tree containing all flux concentrations, via the links_up, links_left, and links_right fields in each Flux::Concentration.
|
| lines | Flux::Fluxon | ro | Holds the top of a tree containing all fluxons in the simulation, via the all_links_up, all_links_left, and all_links_right fields in each Flux::Fluxon.
|
| vertices | Flux::Vertex | ro | Holds the top of a tree containing all vertices in the simulation, via the links_up, links_left, and links_right fields in each Flux::Vertex.
|
| photosphere | Photosphere | rw | The current boundary condition, accessed as a hash ref. The hash ref contains three fields: type, which is an integer - 0 for none, 1 for a plane, 2 for a sphere, 3 for a cylinder; origin, which is a 3-PDL containing the origin of the plane or sphere; and normal, which is a 3-PDL containing the normal vector for a plane or the radius of the sphere (in the 0th element). Modifying the fields in the hash ref doesn't put data back into the WORLD; you have to set the whole photosphere, as in $hash = $a->{photosphere}; $a->{origin}->((0)) += 5; $a->{photosphere} = $hash to move the origin up by five units.
|
| photosphere2 | Photosphere | rw | A second photosphere-like boundary condition, accessed exactly like the photosphere field. This is useful for (e.g.) a bounded photosphere simulation, with an open surface at the top, a photosphere at the bottom, and a bounding cylindrical wall.
|
| image | Flux::Vertex | ro | Holds one of the two vertices of the image segment used for enforcing boundary conditions. Not very useful but present for completeness. |
| image2 | Flux::Vertex | ro | Holds one of the two vertices of the image segment used for enforcing boundary conditions. Not very useful but present for completeness. |
| locale_radius | float | rw | Holds the default locale_radius for newly produced flux concentrations. |
| fc_ob | Concentration | ro | Holds the worldwide "open start" flux concentration, at which all fluxons that start on the open boundary originate. |
| fc_oe | Concentration | ro | Holds the worldwide "open end" flux concentration, at which all fluxons that end on the open boundary terminate. |
| fc_pb | Concentration | ro | Holds the worldwide "plasmoid start" flux concentration, at which all plasmoid fluxons originate. |
| fc_pe | Concentration | ro | Holds the worldwide "plasmoid end" flux concentration, at which all plasmoid fluxons terminate. |
| verbosity | int | rw | Controls the amount of verbiage printed to the screen. 0=minimal, 1=chatty, ..., 6=unusable |
| forces | Forces | rw | Controls the current force laws in effect in the simulation. The force laws are specific named routines in physics.c, and they are delivered and parsed as a Perl list ref of function names. You can set them with $a->{forces} = ['name1','name2',...], though manipulating the individual names (as in $a->{forces}->[2]='name3' # doesn't work) doesn't work. If you need to see a list of currently-recognized forces, just set a field to a random string, and the error message will contain a nice list.
|
| Forces | rw | Contains a list of "mass update" routines to be called in between (and separately from) the force laws. Currently not useful for much, this is part of the massy-plasma infrastructure. | |
| scale_b_power | float | rw | Controls the exponent to which the magnetic field strength is raised, when calculating the step coefficient. |
| scale_d_power | float | rw | Controls the exponent to which the distance between fluxons is raised, when calculating the step coefficient. |
| scale_s_power | float | rw | Controls the exponent to which the stiffness coefficient (average of the ratio: magnitude-sum of forces / sum-magnitude of forces at each vertex) is raised, when calculating the step coefficient. |
| scale_ds_power | float | rw | Controls the exponent to which the differential coefficient between adjacent' vertices' total forces (magnitude-of-difference / magnitude-of-sum) is raised, when calculating the step coefficient. |
| refct | int | rw | Used to account for the number of Perl variables that refer to the world (ie the number of Flux objects floating around in Perl-space, that refer to this world). Don't write to this unless you REALLY know what you are doing. |
| rc_funcs | RCFuncs | rw | Controls the current set of reconnection criteria, and their parameters, that are used to determine where reconnection should happen (when you call the reconnect method). This field is expanded as a list ref, each element of which is itself a list ref containing a function name and a set of parameters for it. You can configure the world by setting this field, though manipulating the subfields of it (without a bulk assignment) won't do anything.
|
| max_angle | float | rw | Holds the calculated maximum angle between adjacent fluxon segments, as of the last update_forces call. Writing is harmless but useless.
|
| mean_angle | float | rw | Holds the calculated mean angle between adjacent fluxon segments, as of the last update_forces call. Writing is harmless but useless.
|
| dtau | float | rw | Controls the relaxation time step, in nominal units of relaxation e-folding widths. The maximum stable value with vertex4 appears to be about 0.125. Typical run value is about 0.1.
|
| rel_step | int | rw | Used to keep track of relaxation step number during relaxation (as distinct from time step in a time-dependent sim; see frame_number, above).
|
| coeffs | Coeffs | rw | Used to control the acceleration coefficients that are intended to speed up relaxations in complex systems. The coefficients are handled as a list ref containing acceleration coefficients by neighbor generation. This is experimental -- leave it at the default value of [1] unless you really know what you are doing.
|
| n_coeffs | int | rw | Used to keep track of how many acceleration coefficients there are. Don't write to this, except possibly to decrement it -- it is set automatically when you assign to coeffs, and increasing it could really screw you up.
|
| maxn_coeffs | int | rw | Largest allowable number of acceleration coefficients. The code won't let you exceed it. Don't write here even though you can. |
| handle_skew | int | rw | Experimental feature flag -- leave this set to 0. |
| auto_open | int | rw | Controls whether field lines should be cut when they cross the open-field boundary. Leave this at 0 for simulations without an open boundary, set it to 1 and adust the location and locale_radius of fc_oe and fc_ob for simulations with an open boundary.
|
| default_bound | Bound | rw | Controls what fluxon end condition is to be used for flux concentrations with no specified boundary handler -- which is most of them. The end condition handlers have specific names, and setting it to an unknown one will print an error message listing them. Setting this to 0 or undef yields standard line-tied behavior; fl_b_tied_inject and fl_b_tied_force prevent instabilities from vertex sparseness, either by injecting new vertices when necessary or by forcing the first nontrivial vertex to lie on a small sphere near the flux concentration.
|
| concurrency | int | rw | Controls how many CPUs are to be used (first-stage parallelization). Setting this to 0 uses single-threaded code. Setting it to 1 uses the first-stage parallelized code, but specifies just a single workhorse (slave) process. Higher values give greater parallelization. |
| f_min, f_max | float | ro | The minimum/maximum force value accumulators (updated during a call to relax_step or relax_step_parallel, below): these values record the min and max total forces on vertices.
|
| fr_min, fr_max | float | ro | The minimum/maximum sum-of-components force value accumulators (updated during a call to relax_step or relax_step_parallel, below).
|
| ca_min,ca_max, ca_acc, ca_ct | float | ro | Cosine-vertex-angle accumulators: these are used to store the min, max, and "average" angle between adjacent segments throughout the sim. The average cosine is ca_acc/ca_ct. (Cosines are used because they are faster to calculate). |
Methods
Constructors & I/O
read_world
$a = read_world($filename);
This just jumps into the read_world defined in io.c, returning an assembled Flux::World object.
write_world
$world->write_world($filename);
This just trampolines into the fprint_world routine found in io.c, writing the World object to a file.
str2world
$world = str2world($str);
Converts a Perl string to a World by the stoopidest possible method -- it currently writes the string to a temporary file, and then calls read_world (above) to read it back in.
string
$str = $world->string;
Generates a Perl string representation of a World. (Currently this is done cheesily, by using fprint_world to write out the World to a file, and then reading the file back in). Because the stringifier in fprint_world is currently the only way to freeze a World, the simplest way to deep-copy a World in memory is:
$world2 = str2world($world1->string); # copy $world1 to $world2
_stringify
print $world;
The _stringify routine is used to overload stringification for World objects, to produce a human readable summary of the World.
stats
print $world->stats->{n_av};
Produces a statistical overview of the simulation, as a hash containing: average force per unit length on each vertex, average unsigned-total force on each vertex, and average number of neighbors per vertex.
summary
print $world->summary
This is meant to produce a longer summary than _stringify (above), but for now it is just a trampoline that calls string (the long-form description).
render
$a->render($iflag, $range, \%options);
This is the generic renderer for FLUX, using PDL's built-in PDL::Graphics::TriD module. It renders images to the default 3-D manipulation window. If $iflag is a true value, then it will wait while the user manipulates the image, until 'q' is entered in the graphics window. If $range is specified, it must be a 2x3-PDL containing opposite corners of a region of interest to render, in 3-space. Many options exist, and can be used to manipulate the rendering (see below).
To generate rendered frames as image files, use the PDL::Graphics::TriD built-in function grabpic3d after calling render. You can also generate rendered movies with simple_relaxer, the autoload file that contains FLUX's demo relaxation loop.
Color values, where present (in the options below) are 3-PDLs with (r,g,b) values in the range [0,1].
Useful options to render are:
- rgb
- If this is specified, it should be a 3-PDL containing a color value that will be used for all fluxons (or, if
rgb_fluxons[below] is not present, all fluxons not named in thergb_fluxonsoption). If neitherrgbnorrgb_fluxonsare named, the fluxons will be colored in a blue-green-red taper, which helps identify north and south poles.
- prgb
- If this is specified, it should be a 3-PDL containing a color value that will be used for all vertices.
- dip_detector
- If present, this should be a 3-PDL containing a color value. Fluxels adjacent to a local minimum in altitude will be colored this color.
- dip_detector2
- If present, this should be a 3-PDL containing a color value. Fluxels between a local minimum and nearby local maximum in altitude will be colored this color. This is different from
dip_detectorin that it colors the entire dip, not just the bottom near the local minimum.
- no_dip
- If present, this is a hash ref whose keys are fluxon IDs and whose values are true. The specified fluxons will not be dip-detected, but will be rendered normally. (This option only makes sense if you're also using
dip_detectorordip_detector2).
- rgb_fluxons
- If present, this is a hash ref whose keys are fluxon IDs and whose values are 3-PDLs containing color values. Named fluxons will be rendered in this color. Any fluxon not found in the hash will be rendered the
rgbcolor or white.
- RGB_CODE
- This is not for the faint of heart -- if present, it should be a code ref, to be executed in the context of the renderer, to calculate the RGB values of individual line segments.
- PRGB_CODE
- If present, contains a code ref in the same style as RGB_CODE that calculates RGB values of individual vertices.
- concentrations
- Flag indicates whether or not to render flux concentrations separately from the points that exist on them. If this is a true value, they will be rendered as large points. By default, they are color coded: blue for north, red for south, white for unknown, yellow for error.
- rgb_fcs
- similar to rgb_fluxons, but for flux concentrations.
- points
- Flag indicating whether or not to draw vertices as rendered points, as well as the line segments (fluxels) between them. (Default is 1).
- psize
- Flag indicating the size of points as rendered. (Default is 4).
- linewidth
- The width (in screen pixels) of rendered line segments. Default is 1; 2-3 is useful for generating figures.
- label
- If this flag is set to a true value, then
renderwill draw numeric labels next to each vertex. This can result in a very cluttered field -- used mainly for debugging.
- neighbors
- If this flag is set to a true value, then
renderwill render the neighbor geometry in the perpendicular midplane to each line segment. Somewhat slow as it requires a fresh neighbor calculation.
- hull
- If this flag is set to a true value, then the hull of each line segment is rendered in the perpendicular midplane of each segment. This is somewhat slow as it requires a fresh neighbor calculation and construction of a great many graphical objects. The hulls are rendered in a dark gold color.
- nscale
- This scaling factor shows the scale at which the perpendicular midplane should be rendered for the
neighborsandhulloptions -- the default is 0.25. Setting it to 1.0 would show the approximate segmentation of space, but generally produces too much clutter.
Access methods for individual fields (deprecated)
These methods provide access to individual pieces of the World data structure, but are largely superseded by the hash interface. They are left in for backwards compatibility.
step_scales
Gives access to the scale_foo fields in the World (see the hash table, above). Called with no arguments, it returns a mini-hash containing the current values. If you supply a mini-hash with some or all of the values in it, then those values are set.
verbosity
Gives access to the verbosity field in the World, which controls how chatty the C library is. If you supply an integer argument, the verbosity is set to that value. Either way it returns the current value.
forces
Gives access to the force list as a list of strings. This can be marginally more convenient than the hash interface, which is required to wrap up the list in a list ref.
reconnection
Gives access to the reconnection routines and their arguments.
boundary/photosphere
Gives access to the photosphere field in the hash.
Multiple-access & search methods
These methods provide bulk read access to large parts of the World. They can in principle be implemented in Perl by traversing the structure via the hash interface, but are much more convenient as-is (and much faster using the C implementation than walking through the Perl hash interface).
concentrations
@concentrations = $world->concentrations;
Returns all flux concentrations (including the special ones between -9 and -1) as a list of Flux::Concentration objects.
concentration
$concentration = $world->concentration($id);
Returns the Flux::Concentration with the given id code (if it exists), or undef (if it doesn't).
fluxon_ids
@nums = $world->fluxon_ids;
Returns a list of all fluxon ids in the World (integers).
fluxons
@fluxons = $world->fluxons;
Returns all the fluxons in the World as a list of Flux::Fluxon objects.
fluxon
$f = $world->fluxon( $num );
Given a fluxon id, returns the fluxon as a Flux::Fluxon object. Returns undef if it doesn't exist.
vertex_ids
@nums = $world->vertex_ids;
Returns all the vertex ids in the World (integers).
vertices
@vertices = $world->vertices;
Returns all the vertices in the World as a list of Flux::Vertex objects.
vertex
$vertex = $world->vertex( $num );
Given a vertex id, returns that vertex as a Flux::Vertex object, or returns undef if it doesn't exist.
polyline
$lines = $world->polyline;
Returns a giant 4xn PDL containing an (x,y,z,pen) polyline for the whole World. Works by calling Flux::Fluxon::polyline for each fluxon, and gluing the results together.
bfield
$bfield = $world->bfield;
Returns a giant 6xn PDL containing (x,y,z,Bx,By,Bz) for every vertex in the World. Works by caling Flux::Fluxon::bfield for each fluxon, and gluing the results together. It doesn't generate new bfield values, only returns the contents of each vertex's cache -- so if you don't have a b_foo force in the force list, or if you haven't recently called update_forces (below), then you will get garbage.
energy
$e = $world->energy;
Returns the total energy stored in the World, in units of Φfluxonl2. It just accumulates the energy value stored in each vertex, so if you don't have a e_foo force in the force list, or if you haven't recently called update_forces (below) then you will get garbage. Relaxation generally causes this energy to go down (and that monotonic trend is a good diagnostic that all is working OK), as the point of relaxation is to minimize the energy, subject to the topological constraint.
dump_vecs
$vecs = $world->dump_vecs;
Returns a 17xn PDL containing the (x,y,z,Bx,By,Bz,Fsx,Fsy,Fsz,Fvx,Fvy,Fvz,rs,rv,rcl) for every vertex in the simulation. Works by calling Flux::Fluxon::dump_vecs for each fluxon, and gluing the results together.
closest_vertex
$vertex = $world->closest_vertex(pdl($x,$y,$z));
$vertex = $world->closest_vertex(pdl($x,$y,$z),1);
$vertex = $world->closest_vertex(pdl($x,$y,$z),0,$vstart)
Returns the Flux::Vertex that is closest to the given point (which must be supplied as a PDL). The second argument is a "global" flag indicating whether the search should be by stepping from neighbor to neighbor (local minimization) or explicit looping over all vertices in the simulation (global minimization). If you supply 0 (local minimization), you can also supply a start vertex if you want, to speed up the search.
Note that local minimization requires you to have already calculated the neighbor links throughout the simulation, using update_neighbors() or something that calls it.
closest_simplex
@vertices = $world->closest_simplex(pdl($x,$y,$z));
Attempts to construct the smallest possible enclosing tetrahedron around your supplied point, using vertices as, er, vertices. In some cases this is impossible, and you get only three nearby vertices.
Similar calling to closest_vertex, just above -- global flag and such. Requires neighbor links in all cases (even if you specify global search) because the simplex construction is always local to the closest vertex found.
Arena manipulation
These methods manipulate the World by advancing or changing the simulation in progress.
fix_proximity
$world->fix_proximity( $ratio )
Adds more vertices as necessary to maintain a proximity limit. The $ratio is the minimum allowable ratio between the distance to the nearest neighbor and the length of the current fluxel -- any fluxel longer than its nearest neighbor distance, divided by $ratio, will be divided into multiple fluxels.
fix_curvature
$world->fix_curvature( $max_curv, $min_curv )
Adds or removes vertices to meet a curvature criterion. Any vertices that hold more than $max_curv radians of curvature will be subdivided into three new vertices. You can leave out $min_curv; if you put it in, then any vertices that have less than $min_curv radians of curvature will be eliminated (provided that the resulting fluxel is not longer than its nearest-neighbor distance).
update_neighbors
$world->update_neighbors($globalflag);
Does a complete hull calculation. Note that you don't have do do this separately in normal operation -- update_force (below) does both a hull calculation and a force calculation simultaneously.
The $globalflag can have values between 0 (false) and 4. In normal operation it should be zero. Originally, the $globalflag was inserted to seed the neighbor relations of each vertex on the first iteration, and in case the localized iterative search didn't work. It turns out that localized iteration is just fine. Furthermore, as of v2.2 the engine now notices new vertices and does a per-vertex global search on them.
So for normal operation, leave $globalflag false.
- 0 or undef
- Normal use -- a next-nearest-neighbor selection is performed to find the neighbor candidates for each fluxel.
- 1
- Use every single fluxel as a neighbor candidate for every other fluxel. Necessary for initial seeding of the model, but runs in O(n2) time.
- 2
- Reduced operation (uses a stripped down set of candidates) for faster use. Deprecated.
- 3
- very stripped down operation (use intermittently if at all) for quite fast performance. Strongly deprecated.
- 4
- Gonzo - ignore everything but previous neighbors. Do not use.
update_neighbors_parallel
$world->update_neighbors_parallel($globalflag)
Same as update_neighbors, but with first-stage parallelization. This is the preferred method to use.
update_force
$world->update_force($globalflag);
Does a complete force calculation including neighbor finding. The $globalflag has the same values as for update_neighbors (above).
update_force_parallel
$world->update_force_parallal($globalflag);
Same as update_force, but with first-stage parallelization.
relax_step
$world->relax_step($dt);
Performs a relaxation step without calculating the forces (you must call update_force before calling relax_step). The $dt is the relaxation tau step size to use -- 0.1 is typical in current usage.
relax_step_parallel
$world->relax_step_parallel($dt);
Same as relax_step, but with first-stage parallelization.
new_concentration
$fc = $world->new_concentration($where, $flux, $label, $end);
Generates a new flux concentration in the world at the given location. $where is a 3-PDL containing the location of the flux concentration. $flux is the amount of flux it will carry. $label is a unique integer label for it, or 0 (in which case FLUX will find a new unique label for you). $end, if specified, is the name of a fluxon end-condition subroutine. Leave blank for normal line-tied operation.
emerge
$source = $world->emerge($source_loc, $sink_loc, $flux, $vertices);
$source = $world->emerge($source_loc, $sink_loc, $flux, $n);
emerge is the opposite of Flux::Concentration::cancel - it produces a pair of flux concentrations, connected by a single fluxon. If you specify $vertices as a 3xN-PDL, then N intermediate vertices will be created, shaping the fluxon exactly. If you only specify $n as a Perl or PDL scalar, then that number of vertices are autocreated, connecting the two concentrations in a straight line.
reconnect
$count = $world->reconnect();
Uses the reconnection criteria already stored in the World, and searches for (and executes) reconnections wherever they apply. Returns the number of reconnections that occurred.
Test harnesses
These are routines and methods that are mainly used for testing some of the C routines, and should not be used in normal operation. They are listed here in case they come in handy for unforeseen tasks.
_ls_dist_test / _p_ls_dist_test
Test the line-segment distance finders in geometry.c.
_projmatrix
Usage: $matrix = Flux::World::_projmatrix($a0,$a1,$a2,$b0,$b1,$b2)
Returns a projection matrix that rotates the vector AB into the positive Z direction. Test harness for projmatrix in geometry.c.
_mat_vmult_3d / _vec_mmult_3d
Test harnesses for the functions of the same names in geometry.c.
_hull_points
Test harness for the function of the same name in geometry.c.
Interpolation
The main interpolation routine is interpolate_value; the ones with leading underscores are for developers.
interpolate_value
$val = $world->interpolate_value($name, $location, $global, $vertex_hint);
$val = $world->interpolate_value($name, $location);
Interpolates the value corresponding to the World::Vertex hash key $name (for example b_vec) from the World's vertices, and returns it. You can only apply this to numeric values or vectors. Numeric scalar values are returned as perl scalars, while vectors are returned as 3-PDLs.
The parameters are:
$name- the name of the value to interpolate
$location- the location to interpolate from (as a 3-PDL; it is not threadable (yet), sorry)
$global- an optional flag indicating whether to use the standard (0) or global (1) vertex search. Normally 0 is OK
$vertex_hint- an optional Flux::Vertex object indicating where to start the localization search. May normally be omitted.
_closest_vertex
$v = $world->_closest_vertex($x, $global, $vertex_hint)
(in World.xs) This is an interface to find_vertex_by_location in geometry.c. $x should be a 3-PDL. You can omit $global and $vertex_hint in most cases. Returns the VERTEX that is closest to the designated point in 3-space.
_closest_simplex
$vertices = $world->_closest_simplex($x, $global, $vertex_hint)
(in World.xs) This is an interface to find_simplex_by_location in geometry.c. Returns a list ref of vertices that form the nearest simplex, or (if the point is not in the interior of the simulation) a smaller collection of vertices. You can omit $global and $vertex_hint in most cases.
_interpolate_value
$val = $world->_interpolate_value($x, $global, $vertex_hint, $offset)
(in World.xs) This is an interface to interpolate_value in geometry.c. Returns the value at the given byte offset from the start of a VERTEX structure, interpolated to the given point using a nearby simplex.
