Skip to content

Commit 082647b

Browse files
committed
Add helper function, help_gen_sample_point(uw_sample_style).
Update solve method to use new helper method. The new method also caches the Badlands coordinate to sample from.
1 parent e5d9ba1 commit 082647b

File tree

1 file changed

+98
-69
lines changed

1 file changed

+98
-69
lines changed

src/underworld/UWGeodynamics/surfaceProcesses.py

Lines changed: 98 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ def _init_model(self):
189189

190190
self._disp_inserted = False
191191

192+
# a cache for badlands information that can be reused in UW coupling.
193+
# The surface grid information from badlands is used to:
194+
# 1. designate material type, _update_material_types.
195+
# 2. used for sampling the velocity field (via help_gen_sample_point).
196+
# store this in bdl_cache
197+
self._bdl_cache = None
198+
192199
# Transfer the initial DEM state to Underworld
193200
self._update_material_types()
194201
comm.Barrier()
@@ -219,57 +226,72 @@ def _generate_dem(self):
219226
dem[:, 2] = coordsZ.flatten()
220227
return dimensionalise(dem, u.meter).magnitude
221228

222-
def solve(self, dt, sigma=0):
223-
"""
224-
Execute Badlands a badlands solve in the Underworld coupling.
225-
1. Collect Badland's recGrid and broadcast to all procs.
226-
2. Inerpolate Underworld velocity field on recGrid
227-
3. Calculate overall displacement in meters by muliplying velocity (m/yr) with input dt (yr).
228-
4. Using the displacement run badlands from currect time `t` to time `t+dt`.
229-
5. Save final stratigraphic field from badlands.
230-
6. Update Underworld particles depending on Badland tin. Another interpolation.
231-
"""
229+
def help_gen_sample_point(self, uw_sample_style=0):
230+
'''
231+
Collective routine. Return sample points.
232232
233-
dt_years = np.round(dimensionalise(dt, u.years).magnitude,6) # fix pint scaling issue
233+
Return:
234+
-------
235+
np.array : shape (dim)
236+
Locations to sample UW velocity.
237+
238+
uw_sample_style : int, 0 default
239+
Style for UW velocity sampling. Possible values 0 or 1.
240+
0 - Use dynamic elevation from Badlands' model elevation. Interpolated to grid locations to sample the UW velocity.
241+
1 - Use OLD method to sample at Badlands' initial recGrid elevations.
242+
243+
Take locations in Badlands' recGrid find the UW velocity field.
244+
This helper function abstracts the different algorithm, based on dim.
245+
This uses cached data, _bdl_cache, from routine _update_material_types().
246+
'''
247+
248+
if uw_sample_style:
249+
# The previous LIMITED implementation.
250+
# LIMITED as it use the static recGrid data from Badlands to sample the UW velocity.
251+
np_surface = None
252+
if rank == 0:
253+
rg = self.badlands_model.recGrid
254+
if self.Model.mesh.dim == 2:
255+
zVals = rg.regZ.mean(axis=1)
256+
np_surface = np.column_stack((rg.regX, zVals))
234257

235-
if rank == 0 and self.verbose:
236-
purple = "\033[0;35m"
237-
endcol = "\033[00m"
238-
print(purple + f"Processing surface with Badlands {dt_years}:\n\t from {self.time_years} -> {self.time_years+dt_years}" + endcol)
239-
sys.stdout.flush()
258+
if self.Model.mesh.dim == 3:
259+
np_surface = np.column_stack((rg.rectX, rg.rectY, rg.rectZ))
260+
261+
np_surface = comm.bcast(np_surface, root=0)
262+
comm.Barrier()
263+
264+
return nd(np_surface * u.meters) # non dimensionalise
265+
266+
## SHOULD only get here is uw_sample_style == 0
240267

241268
fact = dimensionalise(1.0, u.meter).magnitude
242269
if self.Model.mesh.dim == 2:
243270
if rank == 0:
244-
known_xy = self.badlands_model.recGrid.tinMesh['vertices'] / fact
245-
known_z = self.badlands_model.elevation / fact
246-
xs = self.badlands_model.recGrid.regX / fact
271+
xs = self.badlands_model.recGrid.regX / fact # 1D simple
247272
ys = self.badlands_model.recGrid.regY / fact
248273

249-
known_xy = comm.bcast(known_xy, root=0)
250-
known_z = comm.bcast(known_z, root=0)
274+
( known_xy, known_z ) = ( self._bdl_cache[0], self._bdl_cache[1] )
275+
251276
xs = comm.bcast(xs, root=0)
252277
ys = comm.bcast(ys, root=0)
253278

254279
comm.Barrier()
255280

256281
grid_x, grid_y = np.meshgrid(xs, ys)
257-
interpolate_z = griddata(known_xy,
258-
known_z,
259-
(grid_x, grid_y),
282+
interpolate_z = griddata(points=known_xy,
283+
values=known_z,
284+
xi=(grid_x, grid_y),
260285
method='nearest').T
261286
interpolate_z = interpolate_z.mean(axis=1)
262-
nd_coords = np.column_stack((xs, interpolate_z))
287+
return np.column_stack((xs, interpolate_z))
263288

264289
if self.Model.mesh.dim == 3:
265290
if rank == 0:
266-
known_xy = self.badlands_model.recGrid.tinMesh['vertices'] / fact
267-
known_z = self.badlands_model.elevation / fact
268-
rect_x = self.badlands_model.recGrid.rectX / fact
291+
rect_x = self.badlands_model.recGrid.rectX / fact # 1D, every point
269292
rect_y = self.badlands_model.recGrid.rectY / fact
270293

271-
known_xy = comm.bcast(known_xy, root=0)
272-
known_z = comm.bcast(known_z, root=0)
294+
( known_xy, known_z ) = (self._bdl_cache[0], self._bdl_cache[1])
273295
rect_x = comm.bcast(rect_x, root=0)
274296
rect_y = comm.bcast(rect_y, root=0)
275297

@@ -278,7 +300,46 @@ def solve(self, dt, sigma=0):
278300
values=known_z,
279301
xi=(rect_x, rect_y),
280302
method='nearest')
281-
nd_coords = np.column_stack((rect_x,rect_y, interpolate_z))
303+
return np.column_stack((rect_x,rect_y, interpolate_z))
304+
305+
306+
def solve(self, dt, sigma=0, uw_sample_style=0):
307+
"""
308+
Collective routine
309+
310+
Execute Badlands a badlands solve in the Underworld coupling.
311+
312+
Parameters
313+
----------
314+
dt : float,
315+
Non dimensional time to advance badlands forward.
316+
sigma : float, 0 default
317+
Apply a gaussian_filter, as per scipy.ndimage.filters, to the injected velocity displacements from UW to badlands
318+
uw_sample_style : int, 0 default
319+
Style for UW velocity sampling. Possible values 0 or 1.
320+
0 - Use dynamic elevation from Badlands' model elevation. Interpolated to grid locations to sample the UW velocity.
321+
1 - Use OLD method to sample at Badlands' initial recGrid elevations.
322+
323+
Information of function.
324+
Execute Badlands a badlands solve in the Underworld coupling.
325+
1. Collect Badland's recGrid and broadcast to all procs.
326+
2. Inerpolate Underworld velocity field on recGrid
327+
3. Calculate overall displacement in meters by muliplying velocity (m/yr) with input dt (yr).
328+
4. Using the displacement run badlands from currect time `t` to time `t+dt`.
329+
5. TODO: Ensure final stratigraphic field from badlands at `t+dt`.
330+
6. Update Underworld particles depending on Badland tin. Another interpolation.
331+
"""
332+
333+
dt_years = np.round(dimensionalise(dt, u.years).magnitude,6) # fix pint scaling issue
334+
335+
if rank == 0 and self.verbose:
336+
purple = "\033[0;35m"
337+
endcol = "\033[00m"
338+
print(purple + f"Processing surface with Badlands {dt_years}:\n\t from {self.time_years} -> {self.time_years+dt_years}" + endcol)
339+
sys.stdout.flush()
340+
341+
# call the helper function to generate sample point for velocity evaluation
342+
nd_coords = self.help_gen_sample_point(uw_sample_style)
282343

283344
tracer_velocity = self.Model.velocityField.evaluate_global(nd_coords)
284345

@@ -301,43 +362,6 @@ def solve(self, dt, sigma=0):
301362
# Run the Badlands model to the same time point
302363
bdm.run_to_time(run_until)
303364

304-
# # perform final checkpoint to syc
305-
# # time_uw = time_bdm
306-
# # These save are criticle for checkpoint/restart
307-
# # so save them somewhere else
308-
# from badlands import checkPoints
309-
# checkPoints.write_checkpoints(
310-
# bdm.input,
311-
# bdm.recGrid,
312-
# bdm.lGIDs,
313-
# bdm.inIDs,
314-
# bdm.tNow,
315-
# bdm.FVmesh,
316-
# bdm.force,
317-
# bdm.flow,
318-
# bdm.rain,
319-
# bdm.elevation,
320-
# bdm.fillH,
321-
# bdm.cumdiff,
322-
# bdm.cumhill,
323-
# bdm.cumfail,
324-
# bdm.wavediff,
325-
# bdm.outputStep,
326-
# bdm.prop,
327-
# bdm.mapero,
328-
# bdm.cumflex,
329-
# )
330-
331-
# # force a final stratigraphy step
332-
# _ = bdm.strata.buildStrata(
333-
# bdm.elevation,
334-
# bdm.cumdiff,
335-
# bdm.force.sealevel,
336-
# bdm.recGrid.boundsPt,
337-
# 1,
338-
# bdm.outputStep,
339-
# )
340-
341365
self.time_years += dt_years
342366

343367
# TODO: Improve the performance of this function
@@ -372,6 +396,9 @@ def _determine_particle_state_2D(self):
372396
xs = comm.bcast(xs, root=0)
373397
ys = comm.bcast(ys, root=0)
374398

399+
# all procs
400+
self._bdl_cache = (known_xy, known_z)
401+
375402
comm.Barrier()
376403

377404
grid_x, grid_y = np.meshgrid(xs, ys)
@@ -413,6 +440,9 @@ def _determine_particle_state(self):
413440
known_xy = comm.bcast(known_xy, root=0)
414441
known_z = comm.bcast(known_z, root=0)
415442

443+
# all procs
444+
self._bdl_cache = (known_xy, known_z)
445+
416446
comm.Barrier()
417447

418448
volume = self.Model.swarm.particleCoordinates.data
@@ -433,7 +463,6 @@ def _determine_particle_state(self):
433463
return flags
434464

435465
def _update_material_types(self):
436-
437466
# What do the materials (in air/sediment terms) look like now?
438467
if self.Model.mesh.dim == 3:
439468
under_bd_surface = self._determine_particle_state()

0 commit comments

Comments
 (0)