30 #include <sys/select.h> 42 int main (
int argc,
char **argv) {
50 std::cout <<
"ERROR: DFNWorks input and output file " 51 <<
"paths were not included on command line.\n";
55 std::cout <<
"ERROR: DFNWorks output file path " 56 <<
"was not included on command line.\n";
64 std::vector<Poly> acceptedPoly;
65 acceptedPoly.reserve(500);
68 std::vector<IntPoints> intPts;
72 std::vector<Point> triplePoints;
75 std::vector<Shape> shapeFamilies;
90 std::cout <<
"\nh: " <<
h <<
"\n";
95 if (totalFamilies > 0) {
104 std::mt19937_64 generator(
seed);
112 if (totalFamilies > 0 ) {
121 std::cout <<
"\nEstimating number of fractures needed...\n";
133 for (
unsigned int j = 0; j < shapeFamilies.size(); j++) {
135 if (shapeFamilies[j].distributionType == 4) {
139 <<
" using constant size\n";
142 std::cout <<
"Estimated " << shapeFamilies[j].radiiList.size()
143 <<
" fractures for " <<
shapeType(shapeFamilies[j])
159 for (
int i = 0; i < totalFamilies; i++) {
222 int cdfSize = totalFamilies;
224 if (totalFamilies > 0) {
229 std::ofstream radiiAll;
230 std::string output = argv[2];
231 std::string radiiFolder = output +
"/radii";
240 std::string polyFolder = output +
"/polys";
245 std::string file = radiiFolder +
"/radii_All.dat";
246 radiiAll.open(file.c_str(), std::ofstream::out | std::ofstream::trunc);
247 radiiAll <<
"Format: xRadius yRadius Family# (-1 = userRectangle, 0 = userEllipse, > 0 is family in order of famProb)\n";
251 std::uniform_real_distribution<double> uniformDist(0,1);
253 if (totalFamilies > 0) {
271 familyIndex =
indexFromProb(CDF, uniformDist(generator), totalFamilies);
280 struct Poly newPoly =
generatePoly(shapeFamilies[familyIndex], generator, distributions, familyIndex,
true);
284 radiiAll << std::setprecision(8) << newPoly.
xradius <<
" " << newPoly.
yradius 289 int rejectCounter = 0;
291 while (rejectCode != 0) {
322 if (rejectCode != 0) {
328 if(rejectCode == 0) {
344 if (shapeFamilies[familyIndex].layer == 0) {
345 shapeFamilies[familyIndex].currentP32 += newPoly.
area*2/domVol;
348 shapeFamilies[familyIndex].currentP32 += newPoly.
area*2/
layerVol[shapeFamilies[familyIndex].layer-1];
354 if (shapeFamilies[familyIndex].currentP32 >= shapeFamilies[familyIndex].p32Target ) {
357 std::cout <<
"\nP32 For Family " << familyIndex+1 <<
" Completed\n\n";
378 std::cout <<
"Current p32 values per family:\n";
379 for (
int i = 0; i < totalFamilies; i++) {
382 std::cout <<
shapeType(shapeFamilies[i]) <<
" family " 384 <<
" Current P32 = " << std::setprecision(8)
385 << shapeFamilies[i].currentP32;
388 std::cout <<
shapeType(shapeFamilies[i]) <<
" family " 390 <<
" target P32 = " << std::setprecision(8)
391 << shapeFamilies[i].p32Target
392 <<
", " <<
"Current P32 = " << shapeFamilies[i].currentP32;
395 if (
stopCondition == 1 && shapeFamilies[i].p32Target <= shapeFamilies[i].currentP32) {
396 std::cout <<
"...Done\n";
405 acceptedPoly.push_back(newPoly);
433 std::cout <<
"Translating rejected fracture to new position\n";
472 for (
unsigned int i = 0; i < acceptedPoly.size(); i++) {
480 std::string fileName = output +
"/DFN_output.txt";
481 file.open(fileName.c_str(), std::ofstream::out | std::ofstream::trunc);
482 file <<
"\n========================================================\n";
483 file <<
" Network Generation Complete\n";
484 file <<
"========================================================\n";
487 std::cout <<
"\n========================================================\n";
488 std::cout <<
" Network Generation Complete\n";
489 std::cout <<
"========================================================\n";
493 std::cout <<
"\nFinal p32 values per family:\n";
494 for (
int i = 0; i < totalFamilies; i++) {
495 std::cout <<
"Family " << i+1 <<
" target P32 = " << shapeFamilies[i].p32Target
496 <<
", " <<
"Final P32 = " << shapeFamilies[i].currentP32 <<
"\n";
497 file <<
"Family " << i+1 <<
" target P32 = " << shapeFamilies[i].p32Target
498 <<
", " <<
"Final P32 = " << shapeFamilies[i].currentP32 <<
"\n";
503 std::cout <<
"\n________________________________________________________\n";
504 file <<
"\n________________________________________________________\n";
507 double userDefinedShapesArea = 0;
508 double userDefinedVol = 0;
509 double *familyArea =
nullptr;
510 double *familyVol =
nullptr;
511 if (totalFamilies > 0 ) {
512 familyArea =
new double[totalFamilies];
513 familyVol =
new double[totalFamilies];
516 for (
int i = 0; i < totalFamilies; i++) {
523 std::cout <<
"\nStatistics Before Isolated Fractures Removed:\n\n";
524 std::cout <<
"Fractures: " << acceptedPoly.size() <<
"\n";
525 std::cout <<
"Truncated: " << pstats.
truncated <<
"\n\n";
527 file <<
"\nStatistics Before Isolated Fractures Removed:\n\n";
528 file <<
"Fractures: " << acceptedPoly.size() <<
"\n";
529 file <<
"Truncated: " << pstats.
truncated <<
"\n\n";
532 for (
unsigned int i = 0; i < acceptedPoly.size(); i++) {
533 double area = acceptedPoly[i].area;
534 double vol = area * acceptedPoly[i].aperture;
540 familyArea[acceptedPoly[i].familyNum] +=
area;
541 familyVol[acceptedPoly[i].familyNum] += vol;
544 userDefinedShapesArea +=
area;
545 userDefinedVol += vol;
550 std::cout <<
"Total Fractures Volume: " << pstats.
volBeforeRemoval <<
" m^3\n";
551 std::cout <<
"Total Fracture Density (P30): " <<acceptedPoly.size()/domVol <<
"\n";
552 std::cout <<
"Total Fracture Intensity (P32): " << (pstats.
areaBeforeRemoval * 2)/domVol <<
"\n";
553 std::cout <<
"Total Fracture Porosity (P33): " << pstats.
volBeforeRemoval/domVol <<
"\n\n";
557 file <<
"Total Fracture Density (P30): " <<acceptedPoly.size()/domVol <<
"\n";
558 file <<
"Total Fracture Intensity (P32): " << (pstats.
areaBeforeRemoval * 2)/domVol <<
"\n";
559 file <<
"Total Fracture Porosity (P33): " << pstats.
volBeforeRemoval/domVol <<
"\n\n";
562 for (
int i = 0; i < totalFamilies; i++) {
563 std::cout <<
"Family " << i+1 <<
":\n";
567 file <<
"Family " << i+1 <<
":\n";
571 if ( shapeFamilies[i].layer > 0) {
572 int idx = (shapeFamilies[i].layer-1)*2;
573 std::cout <<
" Layer: " << shapeFamilies[i].layer <<
"\n";
574 std::cout <<
" Layer {-z, +z}: {" <<
layers[idx]<<
", " <<
layers[idx+1]<<
"}\n";
575 file <<
" Layer: " << shapeFamilies[i].layer <<
"\n";
576 file <<
" Layer {-z, +z}: {" <<layers[idx]<<
", " <<layers[idx+1]<<
"}\n";
579 std::cout <<
" Layer: Whole Domain \n";
580 file <<
" Layer: Whole Domain \n";
582 std::cout <<
" Surface Area: " << familyArea[i]*2 <<
" m^2\n";
583 std::cout <<
" Volume: " << familyVol[i] <<
" m^3\n";
584 std::cout <<
" Fracture Intensity (P32): " << shapeFamilies[i].currentP32 <<
"\n\n";
586 file <<
" Surface Area: " << familyArea[i]*2 <<
" m^2\n";
587 file <<
" Volume: " << familyVol[i] <<
" m^3\n";
588 file <<
" Fracture Intensity (P32): " << shapeFamilies[i].currentP32 <<
"\n\n";
592 if (userDefinedShapesArea > 0) {
593 std::cout <<
"User Defined: \n";
594 std::cout <<
" Surface Area: " << userDefinedShapesArea*2 <<
" m^2\n";
595 std::cout <<
" Volume: " << userDefinedVol <<
" m^3\n";
596 std::cout <<
" Fracture Intensity (P32): " << userDefinedShapesArea*2/domVol <<
"\n\n";
598 file <<
"User Defined: \n";
599 file <<
" Surface Area: " << userDefinedShapesArea*2 <<
" m^2\n";
600 file <<
" Volume: " << userDefinedVol <<
" m^3\n";
601 file <<
" Fracture Intensity (P32): " << userDefinedShapesArea*2/domVol <<
"\n\n";
607 std::cout <<
"\nRemoving fractures with radius less than " <<
removeFracturesLessThan <<
" and rebuilding DFN\n";
608 file <<
"\nRemoving fractures with radius less than " << removeFracturesLessThan <<
" and rebuilding DFN\n";
609 int size = acceptedPoly.size();
610 removeFractures(removeFracturesLessThan, acceptedPoly, intPts, triplePoints, pstats);
612 std::cout <<
"Removed " << size - acceptedPoly.size() <<
" fractures with radius less than " << removeFracturesLessThan <<
"\n\n";
613 file <<
"Removed " << size - acceptedPoly.size() <<
" fractures with radius less than " << removeFracturesLessThan <<
"\n\n";
617 for (
int i = 0; i < acceptedPoly.size(); i++) {
633 std::vector<unsigned int> finalFractures =
getCluster(pstats);
635 std::sort (finalFractures.begin(), finalFractures.end());
638 bool printConnectivityError = 0;
640 printConnectivityError = 1;
648 if (finalFractures.size() == 0) {
649 std::cout <<
"\nERROR: DFN Generation has finished, however" 650 <<
" there are no intersecting fractures." 651 <<
" Please adjust input parameters.\n";
652 std::cout <<
"Try increasing the fracture density, or shrinking the domain.\n";
654 file <<
"\nERROR: DFN Generation has finished, however" 655 <<
" there are no intersecting fractures." 656 <<
" Please adjust input parameters.\n";
657 file <<
"Try increasing the fracture density, or shrinking the domain.\n";
664 std::cout <<
"\n________________________________________________________\n\n";
665 std::cout <<
"Statistics After Isolated Fractures Removed:\n";
666 std::cout <<
"Final Number of Fractures: " << finalFractures.size() <<
"\n";
667 std::cout <<
"Isolated Fractures Removed: " << acceptedPoly.size() - finalFractures.size() <<
"\n";
668 std::cout <<
"Fractures before isolated fractures removed:: " << acceptedPoly.size() <<
"\n\n";
670 file <<
"\n________________________________________________________\n\n";
671 file <<
"Statistics After Isolated Fractures Removed:\n";
672 file <<
"Final Number of Fractures: " << finalFractures.size() <<
"\n";
673 file <<
"Isolated Fractures Removed: " << acceptedPoly.size() - finalFractures.size() <<
"\n";
674 file <<
"Fractures before isolated fractures removed:: " << acceptedPoly.size() <<
"\n\n";
678 userDefinedShapesArea = 0;
681 if (totalFamilies > 0 ) {
683 for (
int i = 0; i < totalFamilies; i++) {
691 for (
unsigned int i = 0; i < finalFractures.size(); i++) {
692 double area = acceptedPoly[finalFractures[i]].area;
693 double vol = area * acceptedPoly[finalFractures[i]].aperture;
698 if (acceptedPoly[finalFractures[i]].
familyNum >= 0) {
699 familyArea[acceptedPoly[finalFractures[i]].familyNum] +=
area;
700 familyVol[acceptedPoly[finalFractures[i]].familyNum] += vol;
703 userDefinedShapesArea +=
area;
704 userDefinedVol += vol;
709 int *acceptedFromFamCounters =
nullptr;
710 if (totalFamilies > 0) {
711 acceptedFromFamCounters =
new int[totalFamilies];
713 for (
int i = 0; i < totalFamilies; i++) {
715 acceptedFromFamCounters[i] = 0;
718 int size = finalFractures.size();
719 for (
int i = 0; i < size; i++) {
720 if (acceptedPoly[finalFractures[i]].
familyNum >= 0) {
721 acceptedFromFamCounters[acceptedPoly[finalFractures[i]].familyNum]++;
726 std::cout <<
"Total Surface Area: " << pstats.
areaAfterRemoval * 2 <<
" m^2\n";
727 std::cout <<
"Total Fractures Volume: " << pstats.
volAfterRemoval <<
" m^3\n";
728 std::cout <<
"Total Fracture Density (P30): " << finalFractures.size()/domVol <<
"\n";
729 std::cout <<
"Total Fracture Intensity (P32): " << (pstats.
areaAfterRemoval * 2)/domVol <<
"\n";
730 std::cout <<
"Total Fracture Porosity (P33): " << pstats.
volAfterRemoval/domVol <<
"\n\n";
733 file <<
"Total Fractures Volume: " << pstats.
volAfterRemoval <<
" m^3\n";
734 file <<
"Total Fracture Density (P30): " << finalFractures.size()/domVol <<
"\n";
735 file <<
"Total Fracture Intensity (P32): " << (pstats.
areaAfterRemoval * 2)/domVol <<
"\n";
736 file <<
"Total Fracture Porosity (P33): " << pstats.
volAfterRemoval/domVol <<
"\n\n";
739 for (
int i = 0; i < totalFamilies; i++) {
741 std::cout <<
"Family " << i+1 <<
":\n";
742 std::cout <<
" Fractures After Isloated Fracture Removal: " << acceptedFromFamCounters[i] <<
"\n";
743 std::cout <<
" Isolated Fractures Removed: " << pstats.
acceptedFromFam[i] - acceptedFromFamCounters[i] <<
"\n";
747 file <<
"Family " << i+1 <<
":\n";
748 file <<
" Fractures After Isloated Fracture Removal: " << acceptedFromFamCounters[i] <<
"\n";
749 file <<
" Isolated Fractures Removed: " << pstats.
acceptedFromFam[i] - acceptedFromFamCounters[i] <<
"\n";
753 if ( shapeFamilies[i].layer > 0) {
754 int idx = (shapeFamilies[i].layer-1)*2;
755 std::cout <<
" Layer: " << shapeFamilies[i].layer <<
"\n";
756 std::cout <<
" Layer {-z, +z}: {" <<
layers[idx]<<
"," <<
layers[idx+1]<<
"}\n";
758 file <<
" Layer: " << shapeFamilies[i].layer <<
"\n";
759 file <<
" Layer {-z, +z}: {" <<layers[idx]<<
"," <<layers[idx+1]<<
"}\n";
762 std::cout <<
" Layer: Whole Domain \n";
763 file <<
" Layer: Whole Domain \n";
765 std::cout <<
" Surface Area: " << familyArea[i]*2 <<
" m^2\n";
766 std::cout <<
" Volume: " << familyVol[i] <<
" m^3\n";
767 std::cout <<
" Fracture Intesnsity (P32): " << familyArea[i]*2/domVol <<
"\n\n";
769 file <<
" Surface Area: " << familyArea[i]*2 <<
" m^2\n";
770 file <<
" Volume: " << familyVol[i] <<
" m^3\n";
771 file <<
" Fracture Intesnsity (P32): " << familyArea[i]*2/domVol <<
"\n\n";
774 if (userDefinedShapesArea > 0) {
775 std::cout <<
"User Defined Shapes: \n";
776 std::cout <<
" Surface Area: " << userDefinedShapesArea*2 <<
" m^2\n";
777 std::cout <<
" Volume: " << userDefinedVol <<
" m^3\n";
778 std::cout <<
" Fracture Intensity (P32): " << userDefinedShapesArea*2/domVol <<
"\n\n";
780 file <<
"User Defined Shapes: \n";
781 file <<
" Surface Area: " << userDefinedShapesArea*2 <<
" m^2\n";
782 file <<
" Volume: " << userDefinedVol <<
" m^3\n";
783 file <<
" Fracture Intensity (P32): " << userDefinedShapesArea*2/domVol <<
"\n\n";
786 if (acceptedFromFamCounters !=
nullptr) {
787 delete[] acceptedFromFamCounters;
790 std::cout <<
"\n________________________________________________________\n\n";
791 file <<
"\n________________________________________________________\n\n";
793 std::cout <<
"\n" << acceptedPoly.size()<<
" Fractures Accepted (Before Isolated Fracture Removal)\n";
794 std::cout << finalFractures.size()<<
" Final Fractures (After Isolated Fracture Removal)\n\n";
798 file <<
"\n" << acceptedPoly.size()<<
" Fractures Accepted (Before Isolated Fracture Removal)\n";
799 file << finalFractures.size()<<
" Final Fractures (After Isolated Fracture Removal)\n\n";
803 if (printConnectivityError == 1) {
804 std::cout <<
"\nERROR: DFN generation has finished but the formed\n" 805 <<
"fracture network does not make a connection between\n" 806 <<
"the user's specifed boundary faces.\n";
807 std::cout <<
"Try increasing the fracture density, shrinking the domain\n" 808 <<
"or consider using the 'ignoreBoundaryFaces' option.\n";
810 file <<
"\nERROR: DFN generation has finished but the formed\n" 811 <<
"fracture network does not make a connection between\n" 812 <<
"the user's specifed boundary faces.\n";
813 file <<
"Try increasing the fracture density, shrinking the domain\n" 814 <<
"or consider using the 'ignoreBoundaryFaces' option.\n";
821 std::cout <<
"\nNumber of Triple Intersection Points (Before Isolated Fracture Removal): " << triplePoints.size() <<
"\n";
822 file <<
"\nNumber of Triple Intersection Points (Before Isolated Fracture Removal): " << triplePoints.size() <<
"\n";
824 std::cout <<
"\nIntersection Statistics:\n";
825 std::cout <<
" " << pstats.
intersectionsShortened <<
" of " << intPts.size() <<
" Intersections Shortened\n";
826 std::cout <<
" Original Intersection (Before Intersection Shrinking) Length: " << pstats.
originalLength <<
"m\n";
827 std::cout <<
" Intersection Length Discarded: " << pstats.
discardedLength <<
"m\n";
830 file <<
"\nIntersection Statistics:\n";
832 file <<
" Original Intersection (Before Intersection Shrinking) Length: " << pstats.
originalLength <<
"m\n";
833 file <<
" Intersection Length Discarded: " << pstats.
discardedLength <<
"m\n";
837 std::cout <<
"\nRejection Statistics: \n";
846 file <<
"\nRejection Statistics: \n";
856 std::cout <<
"\n________________________________________________________\n\n";
857 file <<
"\n________________________________________________________\n\n";
859 if (totalFamilies > 0) {
861 std::cout <<
"Fracture Estimation statistics:\n";
862 file <<
"Fracture Estimation statistics:\n";
864 std::cout <<
"NOTE: If estimation and actual are very different, \nexpected family distributions might " 865 <<
"not be accurate. \nIf this is the case, try increasing or decreasing \nthe 'radiiListIncrease' option " 866 <<
"in the input file.\n\n";
867 file <<
"NOTE: If estimation and actual are very different, \nexpected family distributions might " 868 <<
"not be accurate. \nIf this is the case, try increasing or decreasing \nthe 'radiiListIncrease' option " 869 <<
"in the input file.\n\n";
872 for (
int i = 0; i < totalFamilies; i++) {
873 if (shapeFamilies[i].distributionType == 4) {
874 std::cout <<
shapeType(shapeFamilies[i]) <<
" Family " 876 <<
"Using constant size\n\n";
878 file <<
shapeType(shapeFamilies[i]) <<
" Family " 880 <<
"Using constant size\n\n";
884 std::cout <<
shapeType(shapeFamilies[i]) <<
" Family " 889 file <<
shapeType(shapeFamilies[i]) <<
" Family " 896 std::cout <<
"\n________________________________________________________\n\n";
897 file <<
"\n________________________________________________________\n\n";
901 std::cout <<
"Seed: " <<
seed <<
"\n";
902 file <<
"Seed: " << seed <<
"\n";
905 writeOutput(argv[2], acceptedPoly, intPts, triplePoints, pstats, finalFractures, shapeFamilies);
910 std::cout <<
"\nLagrit Should Remove " 915 file <<
"\nLagrit Should Remove " void reset_terminal_mode()
void adjustCDF_and_famProb(float *&CDF, float *&famProbability, int &cdfSize, int idx2Remove)
void dryRun(std::vector< Shape > &shapeFamilies, float *shapeProb, std::mt19937_64 &generator, Distributions &distributions)
bool p32Complete(int size)
void insertUserRectsByCoord(std::vector< Poly > &acceptedPoly, std::vector< IntPoints > &intpts, struct Stats &pstats, std::vector< Point > &triplePoints)
unsigned long long int shortIntersection
unsigned long long int closeToNode
unsigned long long int closeToEdge
unsigned long long int triple
void set_conio_terminal_mode()
unsigned int intersectionsShortened
unsigned long long int interCloseToInter
std::string shapeType(struct Shape &shapeFam)
double getArea(struct Poly &poly)
float * createCDF(float *famProb, int size)
struct RejectionReasons rejectionReasons
unsigned long long int closePointToEdge
unsigned int intersectionNodeCount
void insertUserEllByCoord(std::vector< Poly > &acceptedPoly, std::vector< IntPoints > &intpts, struct Stats &pstats, std::vector< Point > &triplePoints)
unsigned long long int outside
std::vector< unsigned int > getCluster(Stats &pstats)
int getFamilyNumber(int familyIndex, int familyShape)
std::vector< unsigned int > rejectsPerAttempt
void addRadiiToLists(float percent, std::vector< Shape > &shapeFamilies, std::mt19937_64 &generator, Distributions &distributions)
void insertUserRects(std::vector< Poly > &acceptedPoly, std::vector< IntPoints > &intpts, struct Stats &pstats, std::vector< Point > &triplePoints)
void writeOutput(char *outputFolder, std::vector< Poly > &acceptedPoly, std::vector< IntPoints > &intPts, std::vector< Point > &triplePoints, struct Stats &pstats, std::vector< unsigned int > &finalFractures, std::vector< Shape > &shapeFamilies)
void assignAperture(struct Poly &newPoly, std::mt19937_64 &generator)
int main(int argc, char **argv)
void assignPermeability(struct Poly &newPoly)
void insertUserEll(std::vector< Poly > &acceptedPoly, std::vector< IntPoints > &intpts, struct Stats &pstats, std::vector< Point > &triplePoints)
void printPolyData(struct Poly &poly)
struct termios orig_termios
void createBoundingBox(struct Poly &newPoly)
unsigned int retranslatedPolyCount
void generateRadiiLists_nPolyOption(std::vector< Shape > &shapeFamilies, float *famProb, std::mt19937_64 &generator, Distributions &distributions)
unsigned int tripleNodeCount
bool domainTruncation(Poly &newPoly, double *domainSize)
int indexFromProb(float *CDF, double roll, int size)
void reTranslatePoly(struct Poly &newPoly, struct Shape &shapeFam, std::mt19937_64 &generator)
struct Poly generatePoly(struct Shape &shapeFam, std::mt19937_64 &generator, Distributions &distributions, int familyIndex, bool useList)
void removeFractures(double minSize, std::vector< Poly > &acceptedPolys, std::vector< IntPoints > &intPts, std::vector< Point > triplePoints, Stats &pstats)
int intersectionChecking(struct Poly &newPoly, std::vector< Poly > &acceptedPoly, std::vector< IntPoints > &intPtsList, struct Stats &pstats, std::vector< Point > &triplePoints)
void printRejectReason(int rejectCode, struct Poly newPoly)
void printShapeFams(std::vector< Shape > &shapeFamilies)
int indexFromProb_and_P32Status(float *CDF, double roll, int famSize, int cdfSize, int &cdfIdx)
void sortRadii(std::vector< Shape > &shapeFam)
unsigned int acceptedPolyCount
unsigned long long int rejectedPolyCount