bool MeshGeneratorGMSH::mesh() { m_isError = !prepare(); // create gmsh files if (writeToGmsh()) { // exec GMSH m_process = QSharedPointer<QProcess>(new QProcess()); m_process.data()->setStandardOutputFile(tempProblemFileName() + ".gmsh.out"); m_process.data()->setStandardErrorFile(tempProblemFileName() + ".gmsh.err"); connect(m_process.data(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(meshGmshError(QProcess::ProcessError))); connect(m_process.data(), SIGNAL(finished(int)), this, SLOT(meshGmshCreated(int))); QString gmshBinary = "gmsh"; if (QFile::exists(QApplication::applicationDirPath() + QDir::separator() + "gmsh.exe")) gmshBinary = "\"" + QApplication::applicationDirPath() + QDir::separator() + "gmsh.exe\""; if (QFile::exists(QApplication::applicationDirPath() + QDir::separator() + "gmsh")) gmshBinary = QApplication::applicationDirPath() + QDir::separator() + "gmsh"; QString triangleGMSH = "%1 -2 \"%2.geo\""; m_process.data()->start(triangleGMSH. arg(gmshBinary). arg(tempProblemFileName()), QIODevice::ReadOnly); // execute an event loop to process the request (nearly-synchronous) QEventLoop eventLoop; connect(m_process.data(), SIGNAL(finished(int)), &eventLoop, SLOT(quit())); connect(m_process.data(), SIGNAL(error(QProcess::ProcessError)), &eventLoop, SLOT(quit())); eventLoop.exec(); } else {
bool MeshGeneratorGMSH::mesh() { m_isError = !prepare(); // create gmsh files if (writeToGmsh()) { Agros2D::log()->printDebug(tr("Mesh generator"), tr("GMSH geometry file was created")); // exec triangle m_process = new QProcess(); m_process->setStandardOutputFile(tempProblemFileName() + ".gmsh.out"); m_process->setStandardErrorFile(tempProblemFileName() + ".gmsh.err"); connect(m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(meshGmshError(QProcess::ProcessError))); connect(m_process, SIGNAL(finished(int)), this, SLOT(meshGmshCreated(int))); QString gmshBinary = "gmsh"; if (QFile::exists(QApplication::applicationDirPath() + QDir::separator() + "gmsh.exe")) gmshBinary = "\"" + QApplication::applicationDirPath() + QDir::separator() + "gmsh.exe\""; if (QFile::exists(QApplication::applicationDirPath() + QDir::separator() + "gmsh")) gmshBinary = QApplication::applicationDirPath() + QDir::separator() + "gmsh"; QString triangleGMSH = "%1 -2 \"%2.geo\""; m_process->start(triangleGMSH. arg(gmshBinary). arg(tempProblemFileName())); // execute an event loop to process the request (nearly-synchronous) QEventLoop eventLoop; connect(m_process, SIGNAL(finished(int)), &eventLoop, SLOT(quit())); eventLoop.exec(); } else {
// meshfilename() char *pythonMeshFileName() { logMessage("pythonMeshFileName()"); if (Util::scene()->sceneSolution()->isMeshed()) return const_cast<char*>(QString(tempProblemFileName() + ".mesh").toStdString().c_str()); else throw invalid_argument(QObject::tr("Problem is not meshed.").toStdString()); }
// solutionfilename() char *pythonSolutionFileName() { logMessage("pythonSolutionFileName()"); if (Util::scene()->sceneSolution()->isSolved()) { char *fileName = const_cast<char*>(QString(tempProblemFileName() + ".sln").toStdString().c_str()); //Util::scene()->sceneSolution()->sln()->save(fileName); return fileName; } else throw invalid_argument(QObject::tr("Problem is not solved.").toStdString()); }
QList<SolutionArray *> SolutionAgros::solveSolutioArray(Hermes::vector<EssentialBCs> bcs) { QTime time; // solution agros array QList<SolutionArray *> solutionArrayList; // load the mesh file mesh = readMeshFromFile(tempProblemFileName() + ".mesh"); refineMesh(mesh, true, true); // create an H1 space Hermes::vector<Space *> space; // create hermes solution array Hermes::vector<Solution *> solution; // create reference solution Hermes::vector<Solution *> solutionReference; // projection norms Hermes::vector<ProjNormType> projNormType; // prepare selector Hermes::vector<RefinementSelectors::Selector *> selector; // error marker bool isError = false; RefinementSelectors::Selector *select = NULL; switch (adaptivityType) { case AdaptivityType_H: select = new RefinementSelectors::HOnlySelector(); break; case AdaptivityType_P: select = new RefinementSelectors::H1ProjBasedSelector(RefinementSelectors::H2D_P_ANISO, Util::config()->convExp, H2DRS_DEFAULT_ORDER); break; case AdaptivityType_HP: select = new RefinementSelectors::H1ProjBasedSelector(RefinementSelectors::H2D_HP_ANISO, Util::config()->convExp, H2DRS_DEFAULT_ORDER); break; } for (int i = 0; i < numberOfSolution; i++) { space.push_back(new H1Space(mesh, &bcs[i], polynomialOrder)); // set order by element for (int j = 0; j < Util::scene()->labels.count(); j++) if (Util::scene()->labels[j]->material != Util::scene()->materials[0]) space.at(i)->set_uniform_order(Util::scene()->labels[j]->polynomialOrder > 0 ? Util::scene()->labels[j]->polynomialOrder : polynomialOrder, QString::number(j).toStdString()); // solution agros array solution.push_back(new Solution()); if (adaptivityType != AdaptivityType_None) { // add norm projNormType.push_back(Util::config()->projNormType); // add refinement selector selector.push_back(select); // reference solution solutionReference.push_back(new Solution()); } } // check for DOFs if (Space::get_num_dofs(space) == 0) { m_progressItemSolve->emitMessage(QObject::tr("DOF is zero"), true); } else { for (int i = 0; i < numberOfSolution; i++) { // transient if (analysisType == AnalysisType_Transient) { // constant initial solution solution.at(i)->set_const(mesh, initialCondition); solutionArrayList.append(solutionArray(solution.at(i))); } // nonlinear if ((linearityType != LinearityType_Linear) && (analysisType != AnalysisType_Transient)) { solution.at(i)->set_const(mesh, 0.0); } } actualTime = 0.0; // update time function Util::scene()->problemInfo()->hermes()->updateTimeFunctions(actualTime); m_wf->set_current_time(actualTime); m_wf->solution = solution; m_wf->delete_all(); m_wf->registerForms(); // emit message if (adaptivityType != AdaptivityType_None) m_progressItemSolve->emitMessage(QObject::tr("Adaptivity type: %1").arg(adaptivityTypeString(adaptivityType)), false); double error = 0.0; // solution int maxAdaptivitySteps = (adaptivityType == AdaptivityType_None) ? 1 : adaptivitySteps; int actualAdaptivitySteps = -1; for (int i = 0; i<maxAdaptivitySteps; i++) { // set up the solver, matrix, and rhs according to the solver selection. SparseMatrix *matrix = create_matrix(matrixSolver); Vector *rhs = create_vector(matrixSolver); Solver *solver = create_linear_solver(matrixSolver, matrix, rhs); if (adaptivityType == AdaptivityType_None) { if (analysisType != AnalysisType_Transient) solve(space, solution, solver, matrix, rhs); } else { // construct globally refined reference mesh and setup reference space. Hermes::vector<Space *> spaceReference = *Space::construct_refined_spaces(space); // assemble reference problem. solve(spaceReference, solutionReference, solver, matrix, rhs); if (!isError) { // project the fine mesh solution onto the coarse mesh. OGProjection::project_global(space, solutionReference, solution, matrixSolver); // Calculate element errors and total error estimate. Adapt adaptivity(space, projNormType); // Calculate error estimate for each solution component and the total error estimate. error = adaptivity.calc_err_est(solution, solutionReference) * 100; // emit signal m_progressItemSolve->emitMessage(QObject::tr("Adaptivity rel. error (step: %2/%3, DOFs: %4/%5): %1%"). arg(error, 0, 'f', 3). arg(i + 1). arg(maxAdaptivitySteps). arg(Space::get_num_dofs(space)). arg(Space::get_num_dofs(spaceReference)), false, 1); // add error to the list m_progressItemSolve->addAdaptivityError(error, Space::get_num_dofs(space)); if (error < adaptivityTolerance || Space::get_num_dofs(space) >= adaptivityMaxDOFs) { break; } if (i != maxAdaptivitySteps-1) adaptivity.adapt(selector, Util::config()->threshold, Util::config()->strategy, Util::config()->meshRegularity); actualAdaptivitySteps = i+1; } if (m_progressItemSolve->isCanceled()) { isError = true; break; } // delete reference space for (int i = 0; i < spaceReference.size(); i++) { delete spaceReference.at(i)->get_mesh(); delete spaceReference.at(i); } spaceReference.clear(); } // clean up. delete solver; delete matrix; delete rhs; } // delete reference solution for (int i = 0; i < solutionReference.size(); i++) delete solutionReference.at(i); solutionReference.clear(); // delete selector if (select) delete select; selector.clear(); // timesteps if (!isError) { SparseMatrix *matrix = NULL; Vector *rhs = NULL; Solver *solver = NULL; // allocate dp for transient solution DiscreteProblem *dpTran = NULL; if (analysisType == AnalysisType_Transient) { // set up the solver, matrix, and rhs according to the solver selection. matrix = create_matrix(matrixSolver); rhs = create_vector(matrixSolver); solver = create_linear_solver(matrixSolver, matrix, rhs); // solver->set_factorization_scheme(HERMES_REUSE_FACTORIZATION_COMPLETELY); dpTran = new DiscreteProblem(m_wf, space, true); } int timesteps = (analysisType == AnalysisType_Transient) ? floor(timeTotal/timeStep) : 1; for (int n = 0; n<timesteps; n++) { // set actual time actualTime = (n+1)*timeStep; // update essential bc values Space::update_essential_bc_values(space, actualTime); // update timedep values Util::scene()->problemInfo()->hermes()->updateTimeFunctions(actualTime); m_wf->set_current_time(actualTime); m_wf->delete_all(); m_wf->registerForms(); // transient if ((timesteps > 1) && (linearityType == LinearityType_Linear)) isError = !solveLinear(dpTran, space, solution, solver, matrix, rhs); if ((timesteps > 1) && (linearityType != LinearityType_Linear)) isError = !solve(space, solution, solver, matrix, rhs); // output for (int i = 0; i < numberOfSolution; i++) { solutionArrayList.append(solutionArray(solution.at(i), space.at(i), error, actualAdaptivitySteps, (n+1)*timeStep)); } if (analysisType == AnalysisType_Transient) m_progressItemSolve->emitMessage(QObject::tr("Transient time step (%1/%2): %3 s"). arg(n+1). arg(timesteps). arg(actualTime, 0, 'e', 2), false, n+2); if (m_progressItemSolve->isCanceled()) { isError = true; break; } } // clean up if (solver) delete solver; if (matrix) delete matrix; if (rhs) delete rhs; if (dpTran) delete dpTran; } } // delete mesh delete mesh; // delete space for (unsigned int i = 0; i < space.size(); i++) { // delete space.at(i)->get_mesh(); delete space.at(i); } space.clear(); // delete last solution for (unsigned int i = 0; i < solution.size(); i++) delete solution.at(i); solution.clear(); if (isError) { for (int i = 0; i < solutionArrayList.count(); i++) delete solutionArrayList.at(i); solutionArrayList.clear(); } return solutionArrayList; }