48 inline static scalar COMBLK(
const scalar a,
const scalar
b)
63 inline static bool obsHasMinSize(
const vector& span,
const PDRparams& tol)
70 (span.x() * span.y() > tol.min_overlap_area)
71 || (span.y() * span.z() > tol.min_overlap_area)
72 || (span.z() * span.x() > tol.min_overlap_area)
87 const PDRblock::location& grid,
90 int *cfmin,
int *cfmax
103 if (olap.size() < grid.nPoints())
106 <<
"The overlap scratch array is too small, has "
107 << olap.size() <<
" but needs " << grid.nPoints() <<
nl
113 if (xmax <= grid.first() || grid.last() <= xmin)
127 xmin = grid.clip(xmin);
128 xmax = grid.clip(xmax);
131 *cmin = grid.findCell(xmin);
132 *cmax = grid.findCell(xmax);
134 for (label ix = *cmin; ix <= *cmax; ++ix)
142 olap[*cmax] = (xmax - xmin) / grid.width(*cmax);
146 if (grid[*cmin] < xmin)
148 olap[*cmin] = (grid[*cmin+1] - xmin) / grid.width(*cmin);
151 if (xmax < grid[*cmax+1])
153 olap[*cmax] = (xmax - grid[*cmax]) / grid.width(*cmax);
156 assert(olap[*cmax] >= 0.0);
181 const UList<scalar>& a_olap, label amin, label amax,
182 const UList<scalar>& b_olap, label bmin, label bmax,
183 SquareMatrix<scalar>& ab_olap
191 amax =
Foam::min(a_olap.size()-1, amax+1);
192 bmax =
Foam::min(b_olap.size()-1, bmax+1);
194 for (label ia = amin; ia <= amax; ++ia)
196 for (label ib = bmin; ib <= bmax; ++ib)
198 ab_olap(ia,ib) = a_olap[ia] * b_olap[ib];
208 scalar ac, scalar bc, scalar dia,
209 scalar theta, scalar wa, scalar wb,
210 const PDRblock::location& agrid, label amin, label amax,
211 const PDRblock::location& bgrid, label bmin, label bmax,
212 SquareMatrix<scalar>& ab_olap,
213 SquareMatrix<scalar>& ab_perim,
214 SquareMatrix<scalar>& a_lblock,
215 SquareMatrix<scalar>& ac_lblock,
216 SquareMatrix<scalar>& c_count,
217 SquareMatrix<symmTensor2D>& c_drag,
218 SquareMatrix<scalar>& b_lblock,
219 SquareMatrix<scalar>& bc_lblock
246 scalar
count, a_lblk, b_lblk, perim, dummy;
256 amax =
Foam::min(amax, agrid.nCells()-1);
257 bmax =
Foam::min(bmax, bgrid.nCells()-1);
259 for (label ia = amin; ia <= amax; ++ia)
262 const scalar a1 = agrid[ia];
263 const scalar a2 = agrid[ia+1];
266 const scalar af1 = agrid.C(ia-1);
267 const scalar af2 = agrid.C(ia);
269 for (label ib = bmin; ib <= bmax; ++ib)
272 const scalar b1 = bgrid[ib];
273 const scalar b2 = bgrid[ib+1];
276 const scalar bf1 = bgrid.C(ib-1);
277 const scalar bf2 = bgrid.C(ib);
284 ac, bc, 0.5*dia, a1, a2, b1, b2, &perim,
285 &dummy, &dummy, &b_lblk, &a_lblk
293 c_drag(ia,ib).xx() = c_drag(ia,ib).yy() = 4.0 * ab_olap(ia,ib) * (a2 - a1) * (b2 - b1) / dia /
mathematical::pi;
294 c_drag(ia,ib).xy() =
Zero;
298 scalar
area = (a2 - a1) * (b2 - b1);
299 scalar rat = dia * dia /
area - 1.5;
302 scalar da = ac - 0.5 * (a1 + a2);
303 scalar db = bc - 0.5 * (b1 + b2);
306 scalar drg0 = c_drag(ia,ib).xx();
307 scalar drg1 = c_drag(ia,ib).yy();
309 c_drag(ia,ib).xx() = drg * ( 1.0 - rat1 ) + drg * da*da/dc/dc * rat1;
310 c_drag(ia,ib).yy() = drg * ( 1.0 - rat1 ) + drg * db*db/dc/dc * rat1;
311 c_drag(ia,ib).xy() = drg * da*db/dc/dc *rat1;
316 ab_olap(ia,ib) =
inters_db( ac, bc, theta, wa, wb, a1, a2, b1, b2, &
count, c_drag(ia,ib), &perim, &a_lblk, &b_lblk, &dummy, &dummy );
317 c_count(ia,ib) = perim / ( wa + wb ) * 0.5;
319 ac_lblock(ia,ib) = a_lblk;
320 bc_lblock(ia,ib) = b_lblk;
321 ab_perim(ia,ib) = perim;
326 if (ac >= af1 && ac < af2)
332 af1, af2, b1, b2, &
count, &dummy, &dummy
339 &perim, &
count, &dummy, &dummy, &dummy
346 ac, bc, theta, wa, wb, af1, af2, b1, b2,
347 &
count, vdrag, &dummy, &a_lblk, &b_lblk, &dummy, &dummy
349 a_lblock(ia,ib) = a_lblk;
355 if (bc >= bf1 && bc < bf2)
360 bc, ac, 0.5*dia, bf1, bf2, a1, a2,
361 &
count, &(vdrag.yy()), &dummy
369 &perim, &dummy, &
count, &dummy, &dummy
376 ac, bc, theta, wa, wb,
378 &
count, vdrag, &dummy, &a_lblk, &b_lblk, &dummy, &dummy
380 b_lblock(ia,ib) = b_lblk;
392 DynamicList<PDRobstacle>& blocks,
393 const labelRange&
range,
394 const scalar multiplier
398 const label nBlock =
range.size();
401 scalar totVolume = 0;
403 if (nBlock < 2)
return 0;
410 DynamicList<PDRobstacle> newBlocks;
413 for (label i1 = 0; i1 < nBlock-1; ++i1)
415 const PDRobstacle& blk1 = blocks[
range[blkOrder[i1]]];
418 const vector max1 = blk1.pt + blk1.span;
424 for (label i2 = i1 + 1; i2 < nBlock; ++i2)
426 const PDRobstacle& blk2 = blocks[
range[blkOrder[i2]]];
429 const vector max2 = blk2.pt + blk2.span;
431 if (max1.x() <= blk2.x())
439 || max1.z() <= blk2.z()
440 || max2.y() <= blk1.y()
441 || max2.z() <= blk1.z()
442 || (blk1.vbkge * blk2.vbkge <= 0)
452 over.pt =
max(blk1.pt, blk2.pt);
453 over.span =
min(max1, max2) - over.pt;
458 assert(blk1.vbkge * blk2.vbkge > 0);
464 over.vbkge = - COMBLK( blk1.vbkge, blk2.vbkge ) * multiplier;
465 over.xbkge = - COMBLK( blk1.xbkge, blk2.xbkge ) * multiplier;
466 over.ybkge = - COMBLK( blk1.ybkge, blk2.ybkge ) * multiplier;
467 over.zbkge = - COMBLK( blk1.zbkge, blk2.zbkge ) * multiplier;
468 over.typeId = 81 + int(15 * multiplier);
470 if (obsHasMinSize(over.span,
pars))
473 totVolume -= over.volume();
475 newBlocks.append(over);
481 blocks.append(std::move(newBlocks));
493 DynamicList<PDRobstacle>& blocks,
494 const labelRange&
range,
495 const UList<PDRobstacle>& cylinders
499 const label nBlock =
range.size();
500 const label nCyl = cylinders.size();
503 scalar totVolume = 0;
505 if (!nBlock || !nCyl)
return 0;
507 scalar
area, a_lblk, b_lblk, dummy, a_centre, b_centre;
518 DynamicList<PDRobstacle> newBlocks;
521 for (label i1 = 0; i1 < nBlock; i1++)
523 const PDRobstacle& blk1 = blocks[
range[blkOrder[i1]]];
526 const vector max1 = blk1.pt + blk1.span;
532 while (i2 < nCyl-1 && cylinders[cylOrder[i2]] < blk1)
537 for (; i2 < nCyl; ++i2)
539 const PDRobstacle& cyl2 = cylinders[cylOrder[i2]];
551 const scalar zm2 = cyl2.z() + cyl2.len();
552 if (blk1.z() > zm2 || cyl2.z() > max1.z())
continue;
554 if ( cyl2.dia() == 0.0 )
558 cyl2.x(), cyl2.y(), cyl2.theta(), cyl2.wa, cyl2.wb,
561 &dummy, dum2, &dummy, &a_lblk, &b_lblk,
569 cyl2.x(), cyl2.y(), 0.5*cyl2.dia(),
572 &dummy, &dummy, &dummy, &dummy, &dummy
576 cyl2.x(), cyl2.y(), 0.5*cyl2.dia(),
579 &dummy, &dummy, &b_centre
583 cyl2.y(), cyl2.x(), 0.5*cyl2.dia(),
586 &dummy, &dummy, &a_centre
599 a_lblk *= blk1.span.x() * ratio;
600 b_lblk *= blk1.span.y() * ratio;
604 over.x() = a_centre - 0.5 * a_lblk;
605 over.y() = b_centre - 0.5 * b_lblk;
606 over.z() =
max(blk1.z(), cyl2.z());
608 over.span.x() = a_lblk;
609 over.span.y() = b_lblk;
610 over.span.z() =
min(max1.z(), cyl2.z() + cyl2.len()) - over.z();
611 assert(over.x() > -200.0);
612 assert(over.x() < 2000.0);
618 const scalar ym2 = cyl2.y() + cyl2.len();
619 if (blk1.y() > ym2 || cyl2.y() > max1.y())
continue;
621 if ( cyl2.dia() == 0.0 )
625 cyl2.z(), cyl2.x(), cyl2.theta(), cyl2.wa, cyl2.wb,
628 &dummy, dum2, &dummy, &a_lblk, &b_lblk,
636 cyl2.z(), cyl2.x(), 0.5*cyl2.dia(),
639 &dummy, &dummy, &dummy, &dummy, &dummy
644 cyl2.z(), cyl2.x(), 0.5*cyl2.dia(),
647 &dummy, &dummy, &b_centre
652 cyl2.x(), cyl2.z(), 0.5*cyl2.dia(),
655 &dummy, &dummy, &a_centre
666 a_lblk *= blk1.span.z() * ratio;
667 b_lblk *= blk1.span.x() * ratio;
669 over.z() = a_centre - a_lblk * 0.5;
670 over.x() = b_centre - b_lblk * 0.5;
671 over.y() =
max(blk1.y(), cyl2.y());
673 over.span.z() = a_lblk;
674 over.span.x() = b_lblk;
675 over.span.y() =
min(max1.y(), cyl2.y() + cyl2.len()) - over.y();
681 const scalar xm2 = cyl2.x() + cyl2.len();
682 if (blk1.x() > xm2 || cyl2.x() > max1.x())
continue;
684 if ( cyl2.dia() == 0.0 )
688 cyl2.y(), cyl2.z(), cyl2.theta(), cyl2.wa, cyl2.wb,
691 &dummy, dum2, &dummy, &a_lblk, &b_lblk,
699 cyl2.y(), cyl2.z(), 0.5*cyl2.dia(),
702 &dummy, &dummy, &dummy, &dummy, &dummy
707 cyl2.y(), cyl2.z(), 0.5*cyl2.dia(),
710 &dummy, &dummy, &b_centre
715 cyl2.z(), cyl2.y(), 0.5*cyl2.dia(),
718 &dummy, &dummy, &a_centre
730 assert(ratio >-10000.0);
731 assert(ratio <10000.0);
732 a_lblk *= blk1.span.y() * ratio;
733 b_lblk *= blk1.span.z() * ratio;
735 over.y() = a_centre - a_lblk * 0.5;
736 over.z() = b_centre - b_lblk * 0.5;
737 over.x() =
max(blk1.x(), cyl2.x());
739 over.span.y() = a_lblk;
740 over.span.z() = b_lblk;
741 over.span.x() =
min(max1.x(), cyl2.x() + cyl2.len()) - over.x();
745 over.vbkge = over.xbkge = over.ybkge = over.zbkge = -1.0;
751 assert(over.x() > -10000.0);
753 if (obsHasMinSize(over.span,
pars))
756 totVolume -= over.volume();
758 newBlocks.append(over);
763 blocks.append(std::move(newBlocks));