31 void gsMarkThreshold(
const std::vector<T> & elError, T refParameter,
32 std::vector<bool> & elMarked)
35 const T maxErr = *std::max_element(elError.begin(), elError.end() );
38 const T Thr = refParameter * maxErr;
40 elMarked.resize( elError.size() );
44 typename std::vector<T>::const_iterator err = elError.begin();
45 for(std::vector<bool>::iterator i = elMarked.begin(); i!= elMarked.end(); ++i, ++err)
50 void gsMarkPercentage(
const std::vector<T> & elError, T refParameter,
51 std::vector<bool> & elMarked)
56 size_t NE = elError.size();
59 std::vector<T> elErrCopy = elError;
63 size_t idxRefineStart = cast<T,size_t>( math::floor( refParameter * (T)(NE) ) );
65 if( idxRefineStart == elErrCopy.size() )
67 GISMO_ASSERT(idxRefineStart >= 1,
"idxRefineStart can't get negative");
76 size_t lastSwapDone = elErrCopy.size() - 1;
77 size_t lastCheckIdx = lastSwapDone;
83 lastCheckIdx = lastSwapDone;
84 for(
size_t i=0; i < lastCheckIdx; i++)
85 if( elErrCopy[i] > elErrCopy[i+1] )
88 elErrCopy[i] = elErrCopy[i+1];
94 }
while( didSwap && (lastSwapDone+1 >= idxRefineStart ) );
97 Thr = elErrCopy[ idxRefineStart ];
98 elMarked.resize( elError.size() );
101 for(
size_t i=0; i < elError.size(); i++)
102 ( elError[i] >= Thr ? elMarked[i] =
true : elMarked[i] =
false );
107 void gsMarkFraction(
const std::vector<T> & elError, T refParameter,
108 std::vector<bool> & elMarked)
114 std::vector<T> elErrCopy = elError;
117 T totalError = (T)(0);
118 for(
size_t i = 0; i < elErrCopy.size(); ++i)
119 totalError += elErrCopy[i];
124 T errorMarkSum = (1-refParameter) * totalError;
125 T cummulErrMarked = 0;
128 GISMO_ASSERT(elErrCopy.size() >= 1,
"elErrCopy needs at least 1 element");
129 size_t lastSwapDone = elErrCopy.size() - 1;
131 for(
size_t i=0; i < lastSwapDone; i++)
132 if( elErrCopy[i] > elErrCopy[i+1] )
135 elErrCopy[i] = elErrCopy[i+1];
136 elErrCopy[i+1] = tmp;
139 cummulErrMarked += elErrCopy[ lastSwapDone ];
142 }
while( cummulErrMarked < errorMarkSum && lastSwapDone > 0 );
145 Thr = elErrCopy[ lastSwapDone + 1 ];
146 elMarked.resize( elError.size() );
149 for(
size_t i=0; i < elError.size(); i++)
150 ( elError[i] >= Thr ? elMarked[i] =
true : elMarked[i] =
false );
197 T refParameter, std::vector<bool> & elMarked)
199 switch (refCriterion)
202 gsMarkThreshold(elError,refParameter,elMarked);
205 gsMarkPercentage(elError,refParameter,elMarked);
208 gsMarkFraction(elError,refParameter,elMarked);
216 std::vector<gsMatrix<T>> gsGetRefinementBoxes( gsMultiBasis<T> & basis,
217 const std::vector<bool> & elMarked)
220 "Incorrect input, num_el="<<basis.totalElements()
221 <<
", mark_vec="<<elMarked.size() );
223 std::vector<gsMatrix<T>> result(basis.nBases());
224 const short_t dim = basis.dim();
229 index_t numMarked, poffset = 0, globalCount = 0;
232 gsMatrix<T> refBoxes;
234 for (
size_t pn=0; pn < basis.nBases(); ++pn )
237 const size_t numEl = basis[pn].numElements();
238 numMarked = std::count_if(elMarked.begin() + poffset,
239 elMarked.begin() + poffset + numEl,
240 GS_BIND2ND(std::equal_to<bool>(),
true) );
242 refBoxes.resize(dim, 2*numMarked);
246 typename gsBasis<T>::domainIter domIt = basis.basis(pn).makeDomainIterator();
247 for (; domIt->good(); domIt->next())
249 if( elMarked[ globalCount++ ] )
253 refBoxes.col(2*numMarked ) = domIt->lowerCorner();
254 refBoxes.col(2*numMarked+1) = domIt->upperCorner();
261 result[pn] = refBoxes;
295 const std::vector<bool> & elMarked,
300 <<
", mark_vec="<<elMarked.size() );
302 std::vector<gsMatrix<T>> boxes = gsGetRefinementBoxes(basis,elMarked);
303 for (
size_t pn=0; pn < basis.
nBases(); ++pn )
306 basis.refine( pn, boxes[pn], refExtension );
311 void gsRefineWithBoxes( gsMultiBasis<T> & basis,
312 const std::vector<gsMatrix<T>> & boxes,
315 for (
size_t pn=0; pn < basis.nBases(); ++pn )
318 basis.refine( pn, boxes[pn], refExtension );
324 const std::vector<bool> & elMarked,
325 int refExtension = 0)
327 const int dim = mp.dim();
332 int numMarked, poffset = 0, globalCount = 0;
335 gsMatrix<T> refBoxes;
337 for (
size_t pn=0; pn < mp.nPatches(); ++pn )
340 const int numEl = mp[pn].basis().numElements();
341 numMarked = std::count_if(elMarked.begin() + poffset,
342 elMarked.begin() + poffset + numEl,
343 GS_BIND2ND(std::equal_to<bool>(),
true) );
346 refBoxes.resize(dim, 2*numMarked);
350 typename gsBasis<T>::domainIter domIt = mp.patch(pn).basis().makeDomainIterator();
351 for (; domIt->good(); domIt->next())
353 if( elMarked[ globalCount++ ] )
357 refBoxes.col(2*numMarked ) =
358 refBoxes.col(2*numMarked+1) = domIt->centerPoint();
365 std::vector<index_t> elements = mp.patch(pn).basis().asElements(refBoxes, refExtension);
366 mp.patch(pn).refineElements( elements );
371 void gsRefineMarkedFunctions(gsMultiPatch<T> & mp,
372 const std::vector<bool> & funMarked,
373 int refExtension = 0)
375 GISMO_ASSERT(funMarked.size()==gsMultiBasis<T>(mp).totalSize(),
"Vector of marked functions must have the same size as the total number of basis functions (over all patches)!");
377 const int dim = mp.dim();
379 int numMarked, poffset = 0, globalCount = 0;
382 gsMatrix<T> refBoxes;
384 for (
size_t pn=0; pn < mp.nPatches(); ++pn )
387 const int numFun = mp[pn].basis().size();
388 numMarked = std::count_if(funMarked.begin() + poffset,
389 funMarked.begin() + poffset + numFun,
390 GS_BIND2ND(std::equal_to<bool>(),
true) );
393 refBoxes.resize(dim, 2*numMarked);
395 for (
index_t i = 0; i != mp.basis(pn).size(); ++i)
396 if (funMarked[globalCount++])
398 refBoxes.block(0,2*numMarked,2,2) = mp.basis(pn).support(i);
403 std::vector<index_t> elements = mp.patch(pn).basis().asElements(refBoxes, refExtension);
405 mp.patch(pn).refineElements( elements );
438 const std::vector<bool> & elMarked,
442 "Incorrect input, num_el="<<basis.numElements()
443 <<
", mark_vec="<<elMarked.
size() );
450 index_t numMarked, poffset = 0, globalCount = 0;
455 for (
size_t pn=0; pn < basis.
nBases(); ++pn )
458 const size_t numEl = basis[pn].numElements();
459 numMarked = std::count_if(elMarked.begin() + poffset,
460 elMarked.begin() + poffset + numEl,
461 GS_BIND2ND(std::equal_to<bool>(),
true) );
463 refBoxes.resize(dim, 2*numMarked);
467 typename gsBasis<T>::domainIter domIt = basis.
basis(pn).makeDomainIterator();
468 for (; domIt->good(); domIt->next())
470 if( elMarked[ globalCount++ ] )
474 refBoxes.col(2*numMarked ) = domIt->lowerCorner();
475 refBoxes.col(2*numMarked+1) = domIt->upperCorner();
483 basis.unrefine( pn, refBoxes, refExtension );
488 void gsProcessMarkedElements(gsMultiBasis<T> & basis,
489 const std::vector<bool> & elRefined,
490 const std::vector<bool> & elCoarsened,
494 const short_t dim = basis.dim();
499 index_t numRefined, numCoarsened, poffset = 0, globalCount = 0;
502 gsMatrix<T> refBoxes, crsBoxes;
504 for (
size_t pn=0; pn < basis.nBases(); ++pn )
507 const size_t numEl = basis[pn].numElements();
508 numRefined = std::count_if(elRefined.begin() + poffset,
509 elRefined.begin() + poffset + numEl,
510 GS_BIND2ND(std::equal_to<bool>(),
true) );
512 numCoarsened = std::count_if(elCoarsened.begin() + poffset,
513 elCoarsened.begin() + poffset + numEl,
514 GS_BIND2ND(std::equal_to<bool>(),
true) );
519 refBoxes.resize(dim, 2*numRefined);
520 crsBoxes.resize(dim, 2*numCoarsened);
525 typename gsBasis<T>::domainIter domIt = basis.basis(pn).makeDomainIterator();
526 for (; domIt->good(); domIt->next())
528 if( elRefined[ globalCount ] )
532 refBoxes.col(2*numRefined ) = domIt->lowerCorner();
533 refBoxes.col(2*numRefined+1) = domIt->upperCorner();
538 if( elCoarsened[ globalCount ] )
542 crsBoxes.col(2*numCoarsened ) = domIt->lowerCorner();
543 crsBoxes.col(2*numCoarsened+1) = domIt->upperCorner();
552 basis.unrefine( pn, crsBoxes, crsExtension);
553 basis.refine( pn, refBoxes, refExtension );
558 void gsProcessMarkedElements(gsMultiPatch<T> & mp,
559 const std::vector<bool> & elRefined,
560 const std::vector<bool> & elCoarsened,
564 const int dim = mp.dim();
569 index_t numRefined, numCoarsened, poffset = 0, globalCount = 0;
572 gsMatrix<T> refBoxes, crsBoxes;
574 for (
size_t pn=0; pn < mp.nPatches(); ++pn )
577 const size_t numEl = mp[pn].basis().numElements();
578 numRefined = std::count_if(elRefined.begin() + poffset,
579 elRefined.begin() + poffset + numEl,
580 GS_BIND2ND(std::equal_to<bool>(),
true) );
582 numCoarsened = std::count_if(elCoarsened.begin() + poffset,
583 elCoarsened.begin() + poffset + numEl,
584 GS_BIND2ND(std::equal_to<bool>(),
true) );
588 refBoxes.resize(dim, 2*numRefined);
589 crsBoxes.resize(dim, 2*numCoarsened);
594 typename gsBasis<T>::domainIter domIt = mp.patch(pn).basis().makeDomainIterator();
595 for (; domIt->good(); domIt->next())
597 if( elRefined[ globalCount ] )
601 refBoxes.col(2*numRefined ) = domIt->lowerCorner();
602 refBoxes.col(2*numRefined+1) = domIt->upperCorner();
607 if( elCoarsened[ globalCount ] )
611 crsBoxes.col(2*numCoarsened ) = domIt->lowerCorner();
612 crsBoxes.col(2*numCoarsened+1) = domIt->upperCorner();
621 std::vector<index_t> elements;
623 elements = mp.patch(pn).basis().asElementsUnrefine(crsBoxes, crsExtension);
624 mp.patch(pn).unrefineElements( elements );
627 elements = mp.patch(pn).basis().asElements(refBoxes, refExtension);
628 mp.patch(pn).refineElements( elements );
635 const std::vector<bool> & elMarked,
636 int refExtension = 0)
638 const int dim = mp.dim();
643 int numMarked, poffset = 0, globalCount = 0;
646 gsMatrix<T> refBoxes;
648 for (
size_t pn=0; pn < mp.nPatches(); ++pn )
651 const int numEl = mp[pn].basis().numElements();
652 numMarked = std::count_if(elMarked.begin() + poffset,
653 elMarked.begin() + poffset + numEl,
654 GS_BIND2ND(std::equal_to<bool>(),
true) );
657 refBoxes.resize(dim, 2*numMarked);
661 typename gsBasis<T>::domainIter domIt = mp.patch(pn).basis().makeDomainIterator();
662 for (; domIt->good(); domIt->next())
664 if( elMarked[ globalCount++ ] )
668 refBoxes.col(2*numMarked ) =
669 refBoxes.col(2*numMarked+1) = domIt->centerPoint();
676 std::vector<index_t> elements = mp.patch(pn).basis().asElementsUnrefine(refBoxes, refExtension);
677 mp.patch(pn).unrefineElements( elements );
682 void gsUnrefineMarkedFunctions(gsMultiPatch<T> & mp,
683 const std::vector<bool> & funMarked,
684 int refExtension = 0)
686 GISMO_ASSERT(funMarked.size()==gsMultiBasis<T>(mp).totalSize(),
"Vector of marked functions must have the same size as the total number of basis functions (over all patches)!");
688 const int dim = mp.dim();
690 int numMarked, poffset = 0, globalCount = 0;
693 gsMatrix<T> refBoxes;
695 for (
size_t pn=0; pn < mp.nPatches(); ++pn )
698 const int numFun = mp[pn].basis().size();
699 numMarked = std::count_if(funMarked.begin() + poffset,
700 funMarked.begin() + poffset + numFun,
701 GS_BIND2ND(std::equal_to<bool>(),
true) );
704 refBoxes.resize(dim, 2*numMarked);
706 for (
index_t i = 0; i != mp.basis(pn).size(); ++i)
707 if (funMarked[globalCount++])
709 refBoxes.block(0,2*numMarked,2,2) = mp.basis(pn).support(i);
714 std::vector<index_t> elements = mp.patch(pn).basis().asElements(refBoxes, refExtension);
716 mp.patch(pn).unrefineElements( elements );
void gsUnrefineMarkedElements(gsMultiBasis< T > &basis, const std::vector< bool > &elMarked, index_t refExtension=0)
Unrefine a gsMultiBasis, based on a vector of element-markings.
Definition: gsAdaptiveRefUtils.h:437
#define short_t
Definition: gsConfig.h:35
int size(size_t i) const
The number of basis functions in basis i.
Definition: gsMultiBasis.h:232
#define index_t
Definition: gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
size_t totalElements() const
The total number of elements in all patches.
Definition: gsMultiBasis.h:255
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
short_t dim() const
Dimension of the parameter domain (must match for all bases).
Definition: gsMultiBasis.h:208
void gsRefineMarkedElements(gsMultiBasis< T > &basis, const std::vector< bool > &elMarked, index_t refExtension=0)
Refine a gsMultiBasis, based on a vector of element-markings.
Definition: gsAdaptiveRefUtils.h:294
const gsBasis< T > & basis(const size_t i) const
Return the i-th basis block.
Definition: gsMultiBasis.h:267
size_t nBases() const
Number of patch-wise bases.
Definition: gsMultiBasis.h:264
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
void gsMarkElementsForRef(const std::vector< T > &elError, int refCriterion, T refParameter, std::vector< bool > &elMarked)
Marks elements/cells for refinement.
Definition: gsAdaptiveRefUtils.h:196