@@ -355,73 +355,99 @@ f(s) instead of s(f)?
355
355
end
356
356
357
357
# Interpolation at arbitrary points (returns -Inf if the point is not found)
358
- Arrays. evaluate! (cache,f:: DistributedCellField ,x:: Point ) = evaluate! (cache, Interpolable (f),x)
359
- Arrays. evaluate! (cache,f:: DistributedCellField ,x:: AbstractVector{<:Point} ) = evaluate! (cache, Interpolable (f),x)
358
+ Arrays. evaluate! (cache,f:: DistributedCellField ,x:: Point ) = evaluate ( Interpolable (f),x)
359
+ Arrays. evaluate! (cache,f:: DistributedCellField ,x:: AbstractVector{<:Point} ) = evaluate ( Interpolable (f),x)
360
360
361
- struct DistributedInterpolable{A} <: Function
361
+ struct DistributedInterpolable{Tx,Ty, A} <: Function
362
362
interps:: A
363
+ function DistributedInterpolable (interps:: AbstractArray{<:Interpolable} )
364
+ Tx,Ty = map (interps) do I
365
+ fi = I. uh
366
+ trian = get_triangulation (fi)
367
+ x = mean (testitem (get_cell_coordinates (trian)))
368
+ return typeof (x), return_type (fi,x)
369
+ end |> tuple_of_arrays
370
+ Tx = getany (Tx)
371
+ Ty = getany (Ty)
372
+ A = typeof (interps)
373
+ new {Tx,Ty,A} (interps)
374
+ end
363
375
end
376
+
364
377
local_views (a:: DistributedInterpolable ) = a. interps
365
378
366
379
function Interpolable (f:: DistributedCellField ;kwargs... )
367
- interps = map (local_views (f)) do fun
368
- Interpolable (fun ,kwargs... )
380
+ interps = map (local_views (f)) do f
381
+ Interpolable (f ,kwargs... )
369
382
end
370
383
DistributedInterpolable (interps)
371
384
end
372
385
373
386
(a:: DistributedInterpolable )(x) = evaluate (a,x)
374
387
375
- function Gridap. Arrays. return_cache (I:: DistributedInterpolable ,x:: Point )
376
- caches = map (local_views (I)) do fi
377
- trian = get_triangulation (fi. uh)
378
- y= mean (testitem (get_cell_coordinates (trian)))
379
- @check typeof (testitem (x)) == typeof (y) " Can only evaluate DistributedInterpolable at physical points of the same dimension of the underlying triangulation"
380
- return_cache (fi,y)
388
+ Arrays. return_cache (f:: DistributedInterpolable ,x:: Point ) = return_cache (f,[x])
389
+ Arrays. evaluate! (caches,I:: DistributedInterpolable ,x:: Point ) = first (evaluate! (caches,I,[x]))
390
+
391
+ function Arrays. return_cache (I:: DistributedInterpolable{Tx,Ty} ,x:: AbstractVector{<:Point} ) where {Tx,Ty}
392
+ msg = " Can only evaluate DistributedInterpolable at physical points of the same dimension of the underlying triangulation"
393
+ @check Tx == eltype (x) msg
394
+ caches = map (local_views (I)) do I
395
+ trian = get_triangulation (I. uh)
396
+ y = mean (testitem (get_cell_coordinates (trian)))
397
+ return_cache (I,y)
381
398
end
382
- caches
399
+ caches
383
400
end
384
- Gridap. Arrays. return_cache (f:: DistributedInterpolable ,x:: AbstractVector{<:Point} ) = Gridap. Arrays. return_cache (f,testitem (x))
385
401
386
- function Gridap. Arrays. evaluate! (caches,I:: DistributedInterpolable ,x:: Point )
387
- y= map (local_views (I),local_views (caches)) do fi,cache
402
+ function Arrays. evaluate! (cache,I:: DistributedInterpolable{Tx,Ty} ,x:: AbstractVector{<:Point} ) where {Tx,Ty}
403
+ _allgather (x) = PartitionedArrays. getdata (getany (gather (x;destination= :all )))
404
+
405
+ # Evaluate in local portions of the domain. Only keep points inside the domain.
406
+ nx = length (x)
407
+ my_ids, my_vals = map (local_views (I),local_views (cache)) do I, cache
408
+ ids = Vector {Int} (undef,nx)
409
+ vals = Vector {Ty} (undef,nx)
410
+ k = 1
411
+ yi = zero (Ty)
412
+ for (i,xi) in enumerate (x)
413
+ inside = true
388
414
try
389
- evaluate! (cache,fi,x )
415
+ yi = evaluate! (cache,I,xi )
390
416
catch
391
- - Inf
417
+ inside = false
392
418
end
393
- end
394
- # reduce(max,y)
395
- z= gather (y)
396
- map_main (local_views (z)) do zi
397
- reduce (max,zi)
398
- end
399
- end
400
-
401
- function Gridap. Arrays. evaluate! (caches,I:: DistributedInterpolable ,v:: AbstractVector{<:Point} )
402
- n= length (local_views (I))
403
- m= length (v)
404
- y= map (local_views (I),local_views (caches)) do fi,cache
405
- w= Vector {Float64} (undef,m)
406
- for (i,x) in enumerate (v)
407
- try
408
- w[i]= evaluate! (cache,fi,x)
409
- catch
410
- w[i]= - Inf
411
- end
419
+ if inside
420
+ ids[k] = i
421
+ vals[k] = yi
422
+ k += 1
412
423
end
413
- return w
414
424
end
415
- # z=gather(y,destination=:all)
416
- z= gather (y)
417
- map_main (local_views (z)) do zi
418
- w= Vector {Float64} (undef,m)
419
- for i= 0 : m- 1
420
- w[i+ 1 ]= reduce (max,zi. data[zi. ptrs[1 : n]. + i])
421
- end
422
- return w
425
+ resize! (ids,k- 1 )
426
+ resize! (vals,k- 1 )
427
+ return ids, vals
428
+ end |> tuple_of_arrays
429
+
430
+ # Communicate results, so that every (id,value) pair is known by every process
431
+ if Ty <: VectorValue
432
+ D = num_components (Ty)
433
+ vals_d = Vector {Vector{eltype(Ty)}} (undef,D)
434
+ for d in 1 : D
435
+ my_vals_d = map (y_p -> map (y_p_i -> y_p_i[d],y_p),my_vals)
436
+ vals_d[d] = _allgather (my_vals_d)
423
437
end
424
- # reduce((v,w)->broadcast(max,v,w),y)
438
+ vals = map (VectorValue,vals_d... )
439
+ else
440
+ vals = _allgather (my_vals)
441
+ end
442
+ ids = _allgather (my_ids)
443
+
444
+ # Combine results
445
+ w = Vector {Ty} (undef,nx)
446
+ for (i,v) in zip (ids,vals)
447
+ w[i] = v
448
+ end
449
+
450
+ return w
425
451
end
426
452
427
453
# Support for distributed Dirac deltas
0 commit comments