Found while adding the linear-exact local RBF interpolator (feature/linear-rbf).
The defect
SwarmVariable._rbf_to_meshVar gathers proxy node values from the particles:
new_coords = meshVar.coords # swarm.py, _rbf_to_meshVar
...
values = kdt.rbf_interpolator_local(new_coords, D, nnn, ...)
MeshVariable.coords dimensionalises when the model has reference quantities active — it returns a UnitAwareArray in metres. The kd-tree it is handed comes from Swarm._get_kdtree(), built from self._particle_coordinates.data, which is non-dimensional, so KDTree.coord_units is None.
ckdtree.KDTree._convert_coords_to_tree_units then raises:
ValueError: KD-tree was built with dimensionless coordinates, but query
coordinates have units 'meter'. Convert to dimensionless first.
So under an active units model the proxy refresh does not work at all. It fails loudly rather than silently corrupting, which is the one piece of good news.
Two more sites have the identical pattern, in IndexSwarmVariable._update_proxy_variables:
kd_swarm.query(self._meshLevelSetVars[0].coords, k=1, sqr_dists=False)
kd.query(self._meshLevelSetVars[0].coords, k=self.nnn, sqr_dists=False)
grep coords_nd src/underworld3/swarm.py returns nothing — the swarm module is the outlier. Code that gets this right: MeshVariable._get_kdtree uses coords_nd; SemiLagrangian uses psi_star[i].coords_nd; _apply_monotone_limit non-dimensionalises explicitly.
Fix
.coords -> .coords_nd at the three sites.
Related
SwarmVariable._create_proxy_variable never forwards units= to the proxy MeshVariable constructor, so a variable created as units="kg/m^3" has var.units == kg/m**3 while var._meshVar.units is None and var.sym is a dimensionless symbol. Probably the same root cause — the proxy path predates the units work.
Test gap
No test exercises a proxied swarm variable under model.set_reference_quantities(...). A regression test should.
A # TODO(BUG): marker pointing here has been added at the _rbf_to_meshVar site on feature/linear-rbf.
Found while adding the linear-exact local RBF interpolator (
feature/linear-rbf).The defect
SwarmVariable._rbf_to_meshVargathers proxy node values from the particles:MeshVariable.coordsdimensionalises when the model has reference quantities active — it returns aUnitAwareArrayin metres. The kd-tree it is handed comes fromSwarm._get_kdtree(), built fromself._particle_coordinates.data, which is non-dimensional, soKDTree.coord_units is None.ckdtree.KDTree._convert_coords_to_tree_unitsthen raises:So under an active units model the proxy refresh does not work at all. It fails loudly rather than silently corrupting, which is the one piece of good news.
Two more sites have the identical pattern, in
IndexSwarmVariable._update_proxy_variables:grep coords_nd src/underworld3/swarm.pyreturns nothing — the swarm module is the outlier. Code that gets this right:MeshVariable._get_kdtreeusescoords_nd;SemiLagrangianusespsi_star[i].coords_nd;_apply_monotone_limitnon-dimensionalises explicitly.Fix
.coords->.coords_ndat the three sites.Related
SwarmVariable._create_proxy_variablenever forwardsunits=to the proxyMeshVariableconstructor, so a variable created asunits="kg/m^3"hasvar.units == kg/m**3whilevar._meshVar.units is Noneandvar.symis a dimensionless symbol. Probably the same root cause — the proxy path predates the units work.Test gap
No test exercises a proxied swarm variable under
model.set_reference_quantities(...). A regression test should.A
# TODO(BUG):marker pointing here has been added at the_rbf_to_meshVarsite onfeature/linear-rbf.