//! \brief Main driver int main(int argc, char** argv) try { try { static const int dim = 3; typedef Dune::CpGrid GridType; if (argc < 2 || strcmp(argv[1],"-h") == 0 || strcmp(argv[1],"--help") == 0 || strcmp(argv[1],"-?") == 0) { syntax(argv); exit(1); } Params p; parseCommandLine(argc,argv,p); Opm::time::StopWatch watch; watch.start(); GridType grid; if (p.file == "uniform") { std::array<int,3> cells; cells[0] = p.cellsx; cells[1] = p.cellsy; cells[2] = p.cellsz; std::array<double,3> cellsize; cellsize[0] = cellsize[1] = cellsize[2] = 1.f; grid.createCartesian(cells,cellsize); } else grid.readEclipseFormat(p.file,p.ctol,false); typedef GridType::ctype ctype; Opm::Elasticity::ElasticityUpscale<GridType> upscale(grid, p.ctol, p.Emin, p.file, p.rocklist, p.verbose); if (p.max[0] < 0 || p.min[0] < 0) { std::cout << "determine side coordinates..." << std::endl; upscale.findBoundaries(p.min,p.max); std::cout << " min " << p.min[0] << " " << p.min[1] << " " << p.min[2] << std::endl; std::cout << " max " << p.max[0] << " " << p.max[1] << " " << p.max[2] << std::endl; } if (p.n1 == -1 || p.n2 == -1) { p.n1 = grid.logicalCartesianSize()[0]; p.n2 = grid.logicalCartesianSize()[1]; } if (p.linsolver.zcells == -1) { double lz = p.max[2]-p.min[2]; int nz = grid.logicalCartesianSize()[2]; double hz = lz/nz; double lp = sqrt((double)(p.max[0]-p.min[0])*(p.max[1]-p.min[1])); int np = std::max(grid.logicalCartesianSize()[0], grid.logicalCartesianSize()[1]); double hp = lp/np; p.linsolver.zcells = (int)(2*hp/hz+0.5); } std::cout << "logical dimension: " << grid.logicalCartesianSize()[0] << "x" << grid.logicalCartesianSize()[1] << "x" << grid.logicalCartesianSize()[2] << std::endl; if (p.method == UPSCALE_MPC) { std::cout << "using MPC couplings in all directions..." << std::endl; upscale.periodicBCs(p.min, p.max); std::cout << "preprocessing grid..." << std::endl; upscale.A.initForAssembly(); } else if (p.method == UPSCALE_MORTAR) { std::cout << "using Mortar couplings.." << std::endl; upscale.periodicBCsMortar(p.min, p.max, p.n1, p.n2, p.lambda[0], p.lambda[1]); } else if (p.method == UPSCALE_NONE) { std::cout << "no periodicity approach applied.." << std::endl; upscale.fixCorners(p.min, p.max); upscale.A.initForAssembly(); } Dune::FieldMatrix<double,6,6> C; Dune::VTKWriter<GridType::LeafGridView>* vtkwriter=0; if (!p.vtufile.empty()) vtkwriter = new Dune::VTKWriter<GridType::LeafGridView>(grid.leafView()); Opm::Elasticity::Vector field[6]; std::cout << "assembling elasticity operator..." << "\n"; upscale.assemble(-1,true); std::cout << "setting up linear solver..." << std::endl; upscale.setupSolvers(p.linsolver); //#pragma omp parallel for schedule(static) for (int i=0; i<6; ++i) { std::cout << "processing case " << i+1 << "..." << std::endl; std::cout << "\tassembling load vector..." << std::endl; upscale.assemble(i,false); std::cout << "\tsolving..." << std::endl; upscale.solve(i); upscale.A.expandSolution(field[i],upscale.u[i]); #define CLAMP(x) (fabs(x)<1.e-4?0.0:x) for (size_t j=0; j<field[i].size(); ++j) { double val = field[i][j]; field[i][j] = CLAMP(val); } Dune::FieldVector<double,6> v; upscale.averageStress(v,upscale.u[i],i); for (int j=0; j<6; ++j) C[i][j] = CLAMP(v[j]); } for (int i=0; i<6; ++i) { std::stringstream str; str << "sol " << i+1; if (vtkwriter) vtkwriter->addVertexData(field[i], str.str().c_str(), dim); } if (vtkwriter) { vtkwriter->write(p.vtufile); delete vtkwriter; } // voigt notation for (int j=0; j<6; ++j) std::swap(C[3][j],C[5][j]); for (int j=0; j<6; ++j) std::swap(C[j][3],C[j][5]); std::cout << "---------" << std::endl; std::cout << C << std::endl; if (!p.output.empty()) { writeOutput(p,watch,grid.size(0),upscale.volumeFractions,C); } return 0; } catch (Dune::Exception &e) { std::cerr << "Dune reported error: " << e << std::endl; } catch (...) { std::cerr << "Unknown exception thrown!" << std::endl; } return 1; } catch (const std::exception &e) { std::cerr << "Program threw an exception: " << e.what() << "\n"; throw; }