int UGFinalizeNoPCLFinalize() { EnableMemTracker(false); ug::GetLogAssistant().flush_error_log(); if (outputProfileStats) { UG_LOG(std::endl); // output the profiled data. PROFILER_UPDATE(); if(GetLogAssistant().is_output_process()) { UG_LOG("\n"); #ifdef UG_PROFILER UG_LOG(ug::GetProfileNode(NULL)->call_tree()); #else PROFILER_OUTPUT(); #endif } #ifdef UG_PROFILER //Shiny::ProfileManager::instance.destroy(); #endif } return 0; }
void UG_LOG_Vector(const VT &vec) { for (size_t i=0; i<vec.size(); ++i) { UG_LOG( vec[i] << " "); } UG_LOG(std::endl); /*{ std::cerr << vec[i] << " "; } std::cerr << std::endl;*/ }
int PartitionMap::get_target_proc(size_t index) { if(index < m_targetProcs.size()) return m_targetProcs[index]; UG_LOG("BAD INDEX in PartitionMap::get_target_proc: " << index); if(num_target_procs() > 0){ UG_LOG(" Max valid index: " << num_target_procs() - 1 << endl); } else{ UG_LOG(" No target processes available.\n"); } return -1; }
bool CreateSmoothHierarchy(MultiGrid& mg, size_t numRefs) { PROFILE_FUNC_GROUP("grid"); IRefinementCallback* refCallback = NULL; // we're only checking for the main attachments here. //todo: improve this - add a domain-based hierarchy creator. if(mg.has_vertex_attachment(aPosition1)) refCallback = new SubdivisionLoopProjector<APosition1>(mg, aPosition1, aPosition1); else if(mg.has_vertex_attachment(aPosition2)) refCallback = new SubdivisionLoopProjector<APosition2>(mg, aPosition2, aPosition2); else if(mg.has_vertex_attachment(aPosition)) refCallback = new SubdivisionLoopProjector<APosition>(mg, aPosition, aPosition); if(!refCallback){ UG_LOG("No standard position attachment found. Aborting.\n"); return false; } GlobalMultiGridRefiner ref(mg, refCallback); for(size_t lvl = 0; lvl < numRefs; ++lvl){ ref.refine(); } if(mg.has_vertex_attachment(aPosition1)) ProjectToLimitPLoop(mg, aPosition1, aPosition1); else if(mg.has_vertex_attachment(aPosition2)) ProjectToLimitPLoop(mg, aPosition2, aPosition2); else if(mg.has_vertex_attachment(aPosition)) ProjectToLimitPLoop(mg, aPosition, aPosition); delete refCallback; return true; }
void initJavaVM(JNIEnv* env) { if (javaVM == NULL) { env->GetJavaVM(&javaVM); } else { UG_LOG("UG-VRL: JavaVM already initialized!" " JavaVM can be initialized only once!"); } }
/// UGLuaWrite. Redirects LUA prints to UG_LOG without adding newline at the end int UGLuaWrite(lua_State *L) { std::stringstream ss; GetToStringFromStack(L, ss); UG_LOG(ss.str()); GetLogAssistant().flush(); return 0; }
/// UGLuaPrint. Redirects LUA prints to UG_LOG int UGLuaPrint(lua_State *L) { std::stringstream ss; GetToStringFromStack(L, ss); ss << "\n"; UG_LOG(ss.str()); return 0; }
bool DeserializeAttachment(Grid& grid, TAttachment& attachment, typename geometry_traits<TElem>::iterator iterBegin, typename geometry_traits<TElem>::iterator iterEnd, BinaryBuffer& in) { if(!grid.has_attachment<TElem>(attachment)) grid.attach_to<TElem>(attachment); // copy data Grid::AttachmentAccessor<TElem, TAttachment> aa(grid, attachment); typedef typename TAttachment::ValueType ValueType; // compare with the magic number int magicNumber = 8304548; int tInt; in.read((char*)&tInt, sizeof(int)); if(tInt != magicNumber){ UG_LOG(" WARNING: magic-number mismatch before read in DeserializeAttachment. Data-salad possible!\n"); return false; } //TODO: remove the following test code. // test: write a number-value to check whether it is send correctly /* number tNum; in.read((char*)&tNum, sizeof(number)); if(tNum != 1247.001234){ UG_LOG("TEST-NUMBER TRANSMIT FAILED in DeserializeAttachment!\n"); return false; } */ for(; iterBegin != iterEnd; ++iterBegin) { in.read((char*)&aa[*iterBegin], sizeof(ValueType)); } in.read((char*)&tInt, sizeof(int)); if(tInt != magicNumber){ UG_LOG(" WARNING: magic-number mismatch after read in DeserializeAttachment. Data-salad possible!\n"); return false; } return true; }
bool checkException(JNIEnv* env, std::string msg, bool throwCPPException) { jthrowable ex = env->ExceptionOccurred(); env->ExceptionClear(); std::string exMsg = getExceptionMessageString(env,ex); if (exMsg!="") { UG_LOG(msg << " (See Java exception for details)"<< std::endl); exMsg = msg + "<font color=\"red\">" + exMsg + "</font>\n"; if (throwCPPException) { UG_THROW(exMsg); } else { UG_LOG(exMsg << std::endl); } } return ex == NULL; }
bool SchurPrecond<TAlgebra>:: check_requirements() { if(m_spDirichletSolver.invalid()) { UG_LOG("ERROR in SchurSolver: No dirichlet solver set " " for inversion of A_{II} in Local Schur complement.\n"); return false; } if(m_spSkeletonSolver.invalid()) { UG_LOG("ERROR in SchurPrecond: No skeleton solver set.\n"); return false; } return true; }
void SchurPrecond<TAlgebra>:: schur_solver_backward(vector_type &u_inner, vector_type &f_inner, vector_type &u_skeleton) { SCHUR_PROFILE_BEGIN(SchurSolverStep_Backward); UG_DLOG(SchurDebug, 3, "\n% 'SchurPrecond::step() - backward':\n"); m_spSchurComplementOp->sub_operator(SD_INNER, SD_SKELETON)->apply(f_inner, u_skeleton); if(!m_spDirichletSolver->apply_return_defect(u_inner, f_inner) ) { UG_LOG("SchurPrecond: Failed to solve inner system!\n"); } }
void DisplayVacantMemory() { bool b = EnableMemTracker(false); bMemTracker = false; for(MemTrackerMap::iterator it = memTracker.begin(); it != memTracker.end(); ++it) { MemTrackerStruct &s = (*it).second; UG_LOG("vacant memory: size = " << GetBytesSizeString(s.size) << ", file " << s.pn->zone->file << " : " << s.pn->zone->line << "\n"); } EnableMemTracker(b); }
bool PartitionMap::change_target_proc(size_t index, int newRank) { // make sure that the given index is valid if(index >= num_target_procs()){ UG_LOG("WARNING in PartitionMap::change_target_proc: Bad index given.\n"); return false; } m_targetProcs[index] = newRank; return true; }
bool TestGridLayoutMap(MultiGrid& mg, GridLayoutMap& glm) { if(mg.has_vertex_attachment(aPosition)) return TestGridLayoutMap(mg, glm, aPosition); else if(mg.has_vertex_attachment(aPosition2)) return TestGridLayoutMap(mg, glm, aPosition2); else if(mg.has_vertex_attachment(aPosition1)) return TestGridLayoutMap(mg, glm, aPosition1); else UG_LOG("ERROR in TestGridLayoutMap: A standard position attachment" " is required.\n"); return false; }
/** This method should be called at the beginning of main(...). * If ug has been compiled for parallel use (UG_PARALLEL is defined) * then this method will internally call pcl::Init. */ int UGInit(int *argcp, char ***argvp, int parallelOutputProcRank) { PROFILE_FUNC(); bool success = true; static bool firstCall = true; if (firstCall) { firstCall = false; #ifdef UG_PARALLEL pcl::Init(argcp, argvp); GetLogAssistant().set_output_process(parallelOutputProcRank); #endif success &= InitPaths((*argvp)[0]); #ifdef UG_BRIDGE try{ bridge::InitBridge(); } catch(UGError& err) { success &= false; UG_LOG("ERROR in UGInit: InitBridge failed!\n"); } #endif if(UGInitPlugins() == false) { success &= false; UG_LOG("ERROR in UGInit: LoadPlugins failed!\n"); } } // convert boolean success == true to int = 0. return !success; }
void CheckAssociatedVolumesOfEdges(Grid& g) { // VOLOPT_STORE_ASSOCIATED_EDGES has to be enabled, so that this method makes sense... if(!g.option_is_enabled(EDGEOPT_STORE_ASSOCIATED_VOLUMES)){ UG_LOG("WARNING: Autoenabling EDGEOPT_STORE_ASSOCIATED_VOLUMES in CheckAssociatedVolumesOfEdges.\n"); g.enable_options(EDGEOPT_STORE_ASSOCIATED_VOLUMES); } g.begin_marking(); // iterate over all volumes for(EdgeIterator iter = g.edges_begin(); iter != g.edges_end(); ++iter){ Edge* e = *iter; g.clear_marks(); // get all associated volumes std::vector<Volume*> vols; CollectAssociated(vols, g, e); // iterate over them and mark them. Make sure none is marked twice. for(size_t i = 0; i < vols.size(); ++i){ if(g.is_marked(vols[i])){ UG_THROW("Volume is contained in associated volumes of edge twice!"); } g.mark(vols[i]); } // now iterate over associated volumes of all corner vertices of e // and make sure that each is marked Edge::ConstVertexArray vrts = e->vertices(); for(size_t i_vrt = 0; i_vrt < e->num_vertices(); ++i_vrt){ CollectAssociated(vols, g, vrts[i_vrt]); for(size_t i_vol = 0; i_vol < vols.size(); ++i_vol){ if(VolumeContains(vols[i_vol], e)){ if(!g.is_marked(vols[i_vol])){ UG_THROW("Volume is contained in edge but not in edge's associated-volume-container!"); } } } } } g.end_marking(); }
bool SolveDeficit(DenseMatrix< VariableArray2<double> > &A, DenseVector<VariableArray1<double> > &x, DenseVector<VariableArray1<double> > &rhs, double deficitTolerance) { DenseMatrix< VariableArray2<double> > A2=A; DenseVector<VariableArray1<double> > rhs2=rhs; UG_ASSERT(A.num_rows() == rhs.size(), ""); UG_ASSERT(A.num_cols() == x.size(), ""); size_t iNonNullRows; x.resize(A.num_cols()); for(size_t i=0; i<x.size(); i++) x[i] = 0.0; std::vector<size_t> interchange; if(Decomp(A, rhs, iNonNullRows, interchange, deficitTolerance) == false) return false; // A.maple_print("Adecomp"); // rhs.maple_print("rhs decomp"); for(int i=iNonNullRows-1; i>=0; i--) { double d=A(i,i); double s=0; for(size_t k=i+1; k<A.num_cols(); k++) s += A(i,k)*x[interchange[k]]; x[interchange[i]] = (rhs[i] - s)/d; } DenseVector<VariableArray1<double> > f; f = A2*x - rhs2; if(VecNormSquared(f) > 1e-2) { UG_LOGN("iNonNullRows = " << iNonNullRows); UG_LOG("solving was wrong:"); UG_LOGN(CPPString(A2, "Aold")); rhs2.maple_print("rhs"); UG_LOGN(CPPString(A, "Adecomp")); rhs.maple_print("rhsDecomp"); x.maple_print("x"); f.maple_print("f"); } return true; }
void SchurPrecond<TAlgebra>:: schur_solve_skeleton(vector_type &u_skeleton, const vector_type &f_skeleton) { SCHUR_PROFILE_BEGIN(SchurSolverStep_SchurSolve); UG_DLOG(SchurDebug, 3, "\n% 'SchurPrecond::step() - skeleton solve':"); if(!f_skeleton.has_storage_type(PST_ADDITIVE)) { UG_THROW("ERROR: In 'SchurPrecond::step':Inadequate storage format of 'f_skeleton'.\n"); } if (!m_spSkeletonSolver->apply(u_skeleton, f_skeleton)) { UG_LOG("SchurPrecond: Failed to solve skeleton system!\n"); } if(!u_skeleton.has_storage_type(PST_CONSISTENT)) { UG_THROW("ERROR: In 'SchurPrecond::step':Inadequate storage format of 'u_skeleton'.\n"); } //UG_LOG("\nu_skeleton="); UG_LOG_Vector<vector_type>(u_skeleton); }
void UGForceExit() { UG_LOG("--- ABORTING UG EXECUTION ---\n"); #ifdef UG_PLUGINS // ? UnloadPlugins(); #endif UGFinalizeNoPCLFinalize(); #ifdef UG_PARALLEL if(pcl::NumProcs() > 1){ // pcl::Abort will terminate execution pcl::Abort(); // !!! this point is not reached !!! } #endif throw(SoftAbort("Exit forced by call to UGForceExit")); }
void TestSubdivision(const char* fileIn, const char* fileOut, int numRefs) { PROFILE_FUNC_GROUP("grid"); //todo: Callbacks have to make sure that their attachment is accessible in the grid. // even if they were initialized before the attachment was attached to the grid. MultiGrid mg; SubsetHandler sh(mg); SubdivisionLoopProjector<APosition> refCallback(mg, aPosition, aPosition); GlobalMultiGridRefiner ref(mg, &refCallback); if(LoadGridFromFile(mg, sh, fileIn)){ for(int lvl = 0; lvl < numRefs; ++lvl){ ref.refine(); } ProjectToLimitPLoop(mg, aPosition, aPosition); SaveGridToFile(mg, mg.get_hierarchy_handler(), fileOut); } else{ UG_LOG("Load failed. aborting...\n"); } }
bool DebugIDManager:: set_debug_level(const char *debugID, int level) { int slen = strlen(debugID); if(slen<=0) return false; if(debugID[slen-1] == '*') { for(size_t i=0; i<m_dbgLevelIdentifiers.size(); i++) { const char *name = m_dbgLevelIdentifiers[i].c_str(); if(WildcardMatch(name, debugID)) { set_debug_level(crc32(name), level); //UG_LOGN(name); } } } else if(set_debug_level(crc32(debugID), level) == false) { UG_LOG("DebugID " << debugID << " not registered.\n"); return false; } return true; }
const typename ConvectionDiffusionFVCR<TDomain>::conv_shape_type& ConvectionDiffusionFVCR<TDomain>:: get_updated_conv_shapes(const FVGeometryBase& geo) { // compute upwind shapes for transport equation // \todo: we should move this computation into the preparation part of the // disc, to only compute the shapes once, reusing them several times. if(m_imVelocity.data_given()) { // get diffusion at ips const MathMatrix<dim, dim>* vDiffusion = NULL; if(m_imDiffusion.data_given()) vDiffusion = m_imDiffusion.values(); // update convection shapes if(!m_spConvShape->update(&geo, m_imVelocity.values(), vDiffusion, true)) { UG_LOG("ERROR in 'ConvectionDiffusionFV1::add_jac_A_elem': " "Cannot compute convection shapes.\n"); } } // return a const (!!) reference to the upwind return *const_cast<const IConvectionShapes<dim>*>(m_spConvShape.get()); }
bool SaveGridToNCDF(Grid& grid, const char* filename, ISubsetHandler* pSH, APosition aPos) { // open the file to which we'll write ofstream out(filename); if(!out) return false; // access subset-handler if(!pSH){ UG_LOG("ERROR: SubsetHandler required for NCDF (Exodus) export.\n"); return false; } ISubsetHandler& sh = *pSH; // access the position attachment if(!grid.has_vertex_attachment(aPos)) return false; if(grid.num_volumes() != grid.num<Tetrahedron>()){ UG_LOG("Saving grid to EXODUS-format.\n" << " WARNING: only Tetrahedrons exported in the moment.\n"); } Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPos); // assign vertex indices AInt aInt; grid.attach_to_vertices(aInt); Grid::VertexAttachmentAccessor<AInt> aaInt(grid, aInt); AssignIndices(grid.vertices_begin(), grid.vertices_end(), aaInt, 1); // write exodus header int var4 = 4; out << "netcdf object {" << endl; out << "dimensions:" << endl; out << "\tlen_string = 33 ;" << endl; out << "\tlen_line = 81 ;" << endl; out << "\tfour = " << var4 << " ;" << endl; out << "\ttime_step = UNLIMITED ;" << endl; out << "\tnum_dim = 3 ;" << endl; out << "\tnum_nodes = " << grid.num_vertices() << " ;" << endl; out << "\tnum_elem = " << grid.num<Tetrahedron>() << " ;" << endl; out << "\tnum_el_blk = " << sh.num_subsets() << " ;" << endl; for(int i = 0; i < sh.num_subsets(); ++i){ GridObjectCollection goc = sh.get_grid_objects_in_subset(i); out << "\tnum_el_in_blk" << i+1 << " = " << goc.num<Tetrahedron>() << " ;" << endl; out << "\tnum_nod_per_el" << i+1 << " = 4 ;" << endl; } out << "\tnum_qa_rec = 1 ;" << endl; // write variables out << endl; out << "variables:" << endl; out << "\tdouble time_whole(time_step) ;" << endl; out << "\tint eb_status(num_el_blk) ;" << endl; out << "\tint eb_prop1(num_el_blk) ;" << endl; out << "\t\teb_prop1:name = \"ID\" ;" << endl; for(int i = 0; i < sh.num_subsets(); ++i){ out << "\tint connect" << i+1 << "(num_el_in_blk" << i+1 << ", num_nod_per_el" << i+1 << ") ;" << endl; out << "\t\tconnect" << i+1 << ":elem_type = \"TETRA4\" ;" << endl; } out << "\tdouble coord(num_dim, num_nodes) ;" << endl; out << "\tchar qa_records(num_qa_rec, four, len_string) ;" << endl; out << "\tchar coor_names(num_dim, len_string) ;" << endl; out << "\tint elem_map(num_elem) ;" << endl; out << "\tint elem_num_map(num_elem) ;" << endl; out << "\tint node_num_map(num_nodes) ;" << endl; out << "// global attributes:" << endl; out << "\t:api_version = 4.01f ;" << endl; out << "\t:version = 3.01f ;" << endl; out << "\t:floating_point_word_size = " << sizeof(number) << " ;" << endl; out << "\t:file_size = 0 ;" << endl; out << "\t:title = \"Exported from lib_grid.\" ;" << endl; // write data out << endl; out << "data:" << endl; out << "eb_status = "; for(int i = 0; i < sh.num_subsets(); ++i){ out << "1"; if(i + 1 < sh.num_subsets()) out << ", "; } out << " ;" << endl << endl; out << "eb_prop1 = "; for(int i = 0; i < sh.num_subsets(); ++i){ out << i+1; if(i + 1 < sh.num_subsets()) out << ", "; } out << " ;" << endl << endl; // write elements for(int i = 0; i < sh.num_subsets(); ++i){ // get the goc for this subset GridObjectCollection goc = sh.get_grid_objects_in_subset(i); out << "connect" << i+1 << " =" << endl; for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl){ for(TetrahedronIterator iter = goc.begin<Tetrahedron>(lvl); iter != goc.end<Tetrahedron>(lvl); ++iter) { // last comma in each row if(iter != goc.begin<Tetrahedron>(lvl)) out << "," << endl; Tetrahedron* tet = *iter; out << " "; out << aaInt[tet->vertex(0)] << ", "; out << aaInt[tet->vertex(1)] << ", "; out << aaInt[tet->vertex(2)] << ", "; out << aaInt[tet->vertex(3)]; } } out << " ;" << endl << endl; } // write coords // x out << "coord =" << endl << " "; size_t endlCounter = 1; for(VertexIterator iter = grid.vertices_begin(); iter != grid.vertices_end(); ++iter, ++endlCounter) { if(endlCounter > 5){ endlCounter = 1; out << endl << " "; } out << " " << aaPos[*iter].x() << ","; } // y for(VertexIterator iter = grid.vertices_begin(); iter != grid.vertices_end(); ++iter, ++endlCounter) { if(endlCounter > 5){ endlCounter = 1; out << endl << " "; } out << " " << aaPos[*iter].y() << ","; } // z for(VertexIterator iter = grid.vertices_begin(); iter != grid.vertices_end(); ++iter, ++endlCounter) { if(iter != grid.vertices_begin()){ out << ","; if(endlCounter > 5){ endlCounter = 1; out << endl << " "; } } out << " " << aaPos[*iter].z(); } out << " ;" << endl << endl; // write qa_records out << "qa_records =" << endl; out << " \"lib_grid\"," << endl; out << " \"...\"," << endl; out << " \"...\"," << endl; out << " \"...\" ;" << endl; // write coor_names out << endl; out << "coor_names =" << endl; out << " \"x\"," << endl; out << " \"y\"," << endl; out << " \"z\" ;" << endl; // write elem_map out << endl; out << "elem_map = "; endlCounter = 1; for(size_t i = 0; i < grid.num<Tetrahedron>(); ++i, ++endlCounter) { out << i+1; if(i+1 < grid.num<Tetrahedron>()){ out << ", "; if(endlCounter > 4){ endlCounter = 0; out << endl << " "; } } } out << " ;" << endl; // write elem_num_map out << endl; out << "elem_num_map = "; endlCounter = 1; for(size_t i = 0; i < grid.num<Tetrahedron>(); ++i, ++endlCounter) { out << i+1; if(i+1 < grid.num<Tetrahedron>()){ out << ", "; if(endlCounter > 4){ endlCounter = 0; out << endl << " "; } } } out << " ;" << endl; // write node_num_map out << endl; out << "node_num_map = "; endlCounter = 1; for(size_t i = 0; i < grid.num<Vertex>(); ++i, ++endlCounter) { out << i+1; if(i+1 < grid.num<Vertex>()){ out << ", "; if(endlCounter > 4){ endlCounter = 0; out << endl << " "; } } } out << " ;" << endl; // close object out << "}" << endl; // remove vertex indices grid.detach_from_vertices(aInt); // done return true; }
/// error function to be used for lua_pcall int luaCallStackError( lua_State *L ) { UG_LOG("LUA-ERROR! Call stack:\n"); ug::bridge::LuaStackTrace(0); return 1; }
bool CustomQuadrilateral<ConcreteQuadrilateralType, BaseClass>:: refine(std::vector<Face*>& vNewFacesOut, Vertex** newFaceVertexOut, Vertex** edgeVrts, Vertex* newFaceVertex, Vertex** pSubstituteVertices, int snapPointIndex) { //TODO: complete quad refine *newFaceVertexOut = newFaceVertex; vNewFacesOut.clear(); // handle substitute vertices. Vertex** vrts; if(pSubstituteVertices) vrts = pSubstituteVertices; else vrts = m_vertices; // check which edges have to be refined and perform the required operations. // get the number of new vertices. uint numNewVrts = 0; for(uint i = 0; i < 4; ++i) { if(edgeVrts[i] != NULL) ++numNewVrts; } switch(numNewVrts) { case 0: // create four new triangles vNewFacesOut.push_back(new Triangle(vrts[0], vrts[1], newFaceVertex)); vNewFacesOut.push_back(new Triangle(vrts[1], vrts[2], newFaceVertex)); vNewFacesOut.push_back(new Triangle(vrts[2], vrts[3], newFaceVertex)); vNewFacesOut.push_back(new Triangle(vrts[3], vrts[0], newFaceVertex)); return true; case 1: { if(newFaceVertex){ assert(!"Problem in CustomQuadrilateral::refine: refine with newFaceVertex and one newEdgeVertex is not yet supported."); return false; } int iNew = -1; for(int i = 0; i < 4; ++i){ if(edgeVrts[i]){ iNew = i; break; } } if(snapPointIndex != -1 && (snapPointIndex == iNew || snapPointIndex == (iNew + 1) % 4)){ UG_LOG("WARNING: Invalid snap-point distribution detected. Ignoring snap-points for this element.\n"); snapPointIndex = -1; } // the corners in a local ordering relative to iNew. Keeping ccw order. Vertex* corner[4]; const int rot = (iNew + 3) % 4; ReorderCornersCCW(corner, vrts, 4, rot); // create the new elements if(snapPointIndex == -1){ vNewFacesOut.push_back(new Triangle(corner[0], corner[1], edgeVrts[iNew])); vNewFacesOut.push_back(new Triangle(corner[0], edgeVrts[iNew], corner[3])); vNewFacesOut.push_back(new Triangle(corner[3], edgeVrts[iNew], corner[2])); } else{ snapPointIndex = (snapPointIndex + 4 - rot) % 4; if(snapPointIndex == 0){ vNewFacesOut.push_back(new Triangle(corner[0], corner[1], edgeVrts[iNew])); vNewFacesOut.push_back(new Quadrilateral(corner[0], edgeVrts[iNew], corner[2], corner[3])); } else if(snapPointIndex == 3){ vNewFacesOut.push_back(new Quadrilateral(corner[0], corner[1], edgeVrts[iNew], corner[3])); vNewFacesOut.push_back(new Triangle(corner[3], edgeVrts[iNew], corner[2])); } else{ UG_THROW("Unexpected snap-point index: " << snapPointIndex << ". This is an implementation error!"); } } return true; } case 2: { if(newFaceVertex){ assert(!"Problem in CustomQuadrilateral::refine: refine with newFaceVertex and two newEdgeVertices is not yet supported."); return false; } // there are two cases (refined edges are adjacent or opposite to each other) int iNew[2]; int counter = 0; for(int i = 0; i < 4; ++i){ if(edgeVrts[i]){ iNew[counter] = i; ++counter; } } // corners will be filled later on Vertex* corner[4]; // check which case applies if(iNew[1] - iNew[0] == 2){ // edges are opposite to each other // the corners in a local ordering relative to iNew[0]. Keeping ccw order. ReorderCornersCCW(corner, vrts, 4, (iNew[0] + 3) % 4); // create new faces vNewFacesOut.push_back(new ConcreteQuadrilateralType(corner[0], corner[1], edgeVrts[iNew[0]], edgeVrts[iNew[1]])); vNewFacesOut.push_back(new ConcreteQuadrilateralType(edgeVrts[iNew[1]], edgeVrts[iNew[0]], corner[2], corner[3])); } else{ // edges are adjacent // we want that (iNew[0] + 1) % 4 == iNew[1] if((iNew[0] + 1) % 4 != iNew[1]) swap(iNew[0], iNew[1]); // the corners in a local ordering relative to iNew[0]. Keeping ccw order. const int rot = (iNew[0] + 3) % 4; ReorderCornersCCW(corner, vrts, 4, rot); if(snapPointIndex != -1 && ((snapPointIndex + 4 - rot) % 4) != 0){ snapPointIndex = -1; UG_LOG("WARNING: Invalid snap-point distribution detected. Ignoring snap-points for this element.\n"); } // create new faces if(snapPointIndex == -1){ vNewFacesOut.push_back(new Triangle(corner[0], corner[1], edgeVrts[iNew[0]])); vNewFacesOut.push_back(new Triangle(edgeVrts[iNew[0]], corner[2], edgeVrts[iNew[1]])); vNewFacesOut.push_back(new Triangle(corner[3], corner[0], edgeVrts[iNew[1]])); vNewFacesOut.push_back(new Triangle(corner[0], edgeVrts[iNew[0]], edgeVrts[iNew[1]])); } else{ vNewFacesOut.push_back(new Triangle(corner[0], corner[1], edgeVrts[iNew[0]])); vNewFacesOut.push_back(new Triangle(corner[3], corner[0], edgeVrts[iNew[1]])); vNewFacesOut.push_back(new Quadrilateral(corner[0], edgeVrts[iNew[0]], corner[2], edgeVrts[iNew[1]])); } } return true; } case 3: { if(newFaceVertex){ assert(!"Problem in CustomQuadrilateral::refine: refine with newFaceVertex and three newEdgeVertices is not yet supported."); return false; } int iFree = -1; for(int i = 0; i < 4; ++i){ if(!edgeVrts[i]){ iFree = i; break; } } // the vertices on the edges: Vertex* nvrts[3]; nvrts[0] = edgeVrts[(iFree + 1) % 4]; nvrts[1] = edgeVrts[(iFree + 2) % 4]; nvrts[2] = edgeVrts[(iFree + 3) % 4]; // the corners in a local ordering relative to iNew. Keeping ccw order. Vertex* corner[4]; ReorderCornersCCW(corner, vrts, 4, (iFree + 1) % 4); // create the faces vNewFacesOut.push_back(new ConcreteQuadrilateralType(corner[0], nvrts[0], nvrts[2], corner[3])); vNewFacesOut.push_back(new Triangle(corner[1], nvrts[1], nvrts[0])); vNewFacesOut.push_back(new Triangle(corner[2], nvrts[2], nvrts[1])); vNewFacesOut.push_back(new Triangle(nvrts[0], nvrts[1], nvrts[2])); return true; } case 4: { // we'll create 4 new quads. create a new center if required. if(!newFaceVertex) newFaceVertex = new RegularVertex; *newFaceVertexOut = newFaceVertex; vNewFacesOut.push_back(new ConcreteQuadrilateralType(vrts[0], edgeVrts[0], newFaceVertex, edgeVrts[3])); vNewFacesOut.push_back(new ConcreteQuadrilateralType(vrts[1], edgeVrts[1], newFaceVertex, edgeVrts[0])); vNewFacesOut.push_back(new ConcreteQuadrilateralType(vrts[2], edgeVrts[2], newFaceVertex, edgeVrts[1])); vNewFacesOut.push_back(new ConcreteQuadrilateralType(vrts[3], edgeVrts[3], newFaceVertex, edgeVrts[2])); return true; } } return false; }
void ntree<tree_dim, world_dim, elem_t, common_data_t>:: split_leaf_node(size_t nodeIndex) { if(m_nodes[nodeIndex].numEntries <= 1) return; if(m_nodes[nodeIndex].level >= m_desc.maxDepth){ if(m_warningsEnabled){ UG_LOG("WARNING in ntree::split_leaf_node(): maximum tree depth " << m_desc.maxDepth << " reached. No further splits are performed for " " this node. Note that too many elements per node may lead to performance issues.\n" << " Number of elements in this node: " << m_nodes[nodeIndex].numEntries << std::endl << " Corner coordinates of this node: " << m_nodes[nodeIndex].tightBox << std::endl); } return; } if(m_nodes[nodeIndex].childNodeInd[0] != s_invalidIndex) return; const size_t firstChild = m_nodes.size(); m_nodes.resize(firstChild + s_numChildren); // ATTENTION: Be careful not to resize m_nodes while using node, since this would invalidate the reference! Node& node = m_nodes[nodeIndex]; // calculate center of mass and use the traits class to split the box of // the current node into 's_numChildren' child boxes. Each child box thereby // spanned by one of the corners of the original box and 'centerOfMass'. vector_t centerOfMass = calculate_center_of_mass(node); box_t childBoxes[s_numChildren]; traits::split_box(childBoxes, node.tightBox, centerOfMass); // iterate over all entries in the current node and assign them to child nodes. size_t numEntriesAssigned = 0; for(size_t entryInd = node.firstEntryInd; entryInd != s_invalidIndex;){ Entry& entry = m_entries[entryInd]; size_t nextEntryInd = entry.nextEntryInd; size_t i_child; vector_t center; traits::calculate_center(center, entry.elem, m_commonData); for(i_child = 0; i_child < s_numChildren; ++i_child){ if(traits::box_contains_point(childBoxes[i_child], center)){ add_entry_to_node(m_nodes[firstChild + i_child], entryInd); ++numEntriesAssigned; break; } } /*-- For debugging only: --* if(i_child == s_numChildren){ UG_LOG ("ERROR in ntree::split_leaf_node(): Element with center @ " << center << " does not belong to any child of the box " << node.tightBox << std::endl); } *--*/ entryInd = nextEntryInd; } // all elements of the current box now should be assigned to child boxes. // we thus clear element lists and entry-count from the current node. UG_COND_THROW(numEntriesAssigned != node.numEntries, "Couldn't find a matching " "child node for some elements during split_leaf_node in " "ntree::split_leaf_node"); node.firstEntryInd = node.lastEntryInd = s_invalidIndex; node.numEntries = 0; for(size_t i_child = 0; i_child < s_numChildren; ++i_child){ node.childNodeInd[i_child] = firstChild + i_child; Node& childNode = m_nodes[firstChild + i_child]; childNode.level = node.level + 1; childNode.tightBox = childBoxes[i_child]; update_loose_bounding_box(childNode); } // since split_leaf_node resizes m_nodes and since this invalidates any references // to m_nodes, we perform the recursion in a last step for(size_t i_child = 0; i_child < s_numChildren; ++i_child){ size_t childNodeInd = firstChild + i_child; if(m_nodes[childNodeInd].numEntries >= m_desc.splitThreshold) split_leaf_node(childNodeInd); } }
bool TestGridLayoutMap(MultiGrid& mg, GridLayoutMap& glm, TAPos& aPos) { typedef typename TAPos::ValueType TValue; typedef VertexLayout::LevelLayout VrtLevelLayout; typedef EdgeLayout::LevelLayout EdgeLevelLayout; typedef FaceLayout::LevelLayout FaceLevelLayout; bool bSuccess = true; const bool verbose = true; // check the interfaces pcl::InterfaceCommunicator<VertexLayout::LevelLayout> comVrt; pcl::ProcessCommunicator procCom; ToElementPosition<Vertex, TAPos> toPosVrt(mg, aPos); UG_LOG("Testing horizontal vertex layouts...\n"); { VertexLayout& masterLayout = glm.get_layout<Vertex>(INT_H_MASTER); VertexLayout& slaveLayout = glm.get_layout<Vertex>(INT_H_SLAVE); // we have to retrieve the max level of all layouts int locMaxLevel = max(slaveLayout.num_levels(), masterLayout.num_levels()); int globMaxLevel = locMaxLevel; procCom.allreduce(&locMaxLevel, &globMaxLevel, 1, PCL_DT_INT, PCL_RO_MAX); for(int i = 0; i < globMaxLevel; ++i){ if(verbose){ UG_LOG("Testing VertexLayout on level " << i << ":" << endl); } bSuccess &= pcl::TestLayout<VrtLevelLayout, TValue>(procCom, comVrt, masterLayout.layout_on_level(i), slaveLayout.layout_on_level(i), verbose, toPosVrt, true); } } UG_LOG("Testing vertical vertex layouts...\n"); { VertexLayout& masterLayout = glm.get_layout<Vertex>(INT_V_MASTER); VertexLayout& slaveLayout = glm.get_layout<Vertex>(INT_V_SLAVE); int locMaxLevel = max(slaveLayout.num_levels(), masterLayout.num_levels()); int globMaxLevel = locMaxLevel; procCom.allreduce(&locMaxLevel, &globMaxLevel, 1, PCL_DT_INT, PCL_RO_MAX); for(int i = 0; i < globMaxLevel; ++i){ if(verbose){ UG_LOG("Testing VertexLayout on level " << i << ":" << endl); } bSuccess &= pcl::TestLayout<VrtLevelLayout, TValue>(procCom, comVrt, masterLayout.layout_on_level(i), slaveLayout.layout_on_level(i), verbose, toPosVrt, true); } } pcl::InterfaceCommunicator<EdgeLayout::LevelLayout> comEdge; ToElementPosition<Edge, TAPos> toPosEdge(mg, aPos); UG_LOG("Testing horizontal edge layouts...\n"); { EdgeLayout& masterLayout = glm.get_layout<Edge>(INT_H_MASTER); EdgeLayout& slaveLayout = glm.get_layout<Edge>(INT_H_SLAVE); // we have to retrieve the max level of all layouts int locMaxLevel = max(slaveLayout.num_levels(), masterLayout.num_levels()); int globMaxLevel = locMaxLevel; procCom.allreduce(&locMaxLevel, &globMaxLevel, 1, PCL_DT_INT, PCL_RO_MAX); for(int i = 0; i < globMaxLevel; ++i){ if(verbose){ UG_LOG("Testing EdgeLayout on level " << i << ":" << endl); } bSuccess &= pcl::TestLayout<EdgeLevelLayout, TValue>(procCom, comEdge, masterLayout.layout_on_level(i), slaveLayout.layout_on_level(i), verbose, toPosEdge, true); } } UG_LOG("Testing vertical edge layouts...\n"); { EdgeLayout& masterLayout = glm.get_layout<Edge>(INT_V_MASTER); EdgeLayout& slaveLayout = glm.get_layout<Edge>(INT_V_SLAVE); int locMaxLevel = max(slaveLayout.num_levels(), masterLayout.num_levels()); int globMaxLevel = locMaxLevel; procCom.allreduce(&locMaxLevel, &globMaxLevel, 1, PCL_DT_INT, PCL_RO_MAX); for(int i = 0; i < globMaxLevel; ++i){ if(verbose){ UG_LOG("Testing EdgeLayout on level " << i << ":" << endl); } bSuccess &= pcl::TestLayout<EdgeLevelLayout, TValue>(procCom, comEdge, masterLayout.layout_on_level(i), slaveLayout.layout_on_level(i), verbose, toPosEdge, true); } } pcl::InterfaceCommunicator<FaceLayout::LevelLayout> comFace; ToElementPosition<Face, TAPos> toPosFace(mg, aPos); UG_LOG("Testing horizontal face layouts...\n"); { FaceLayout& masterLayout = glm.get_layout<Face>(INT_H_MASTER); FaceLayout& slaveLayout = glm.get_layout<Face>(INT_H_SLAVE); // we have to retrieve the max level of all layouts int locMaxLevel = max(slaveLayout.num_levels(), masterLayout.num_levels()); int globMaxLevel = locMaxLevel; procCom.allreduce(&locMaxLevel, &globMaxLevel, 1, PCL_DT_INT, PCL_RO_MAX); for(int i = 0; i < globMaxLevel; ++i){ if(verbose){ UG_LOG("Testing FaceLayout on level " << i << ":" << endl); } bSuccess &= pcl::TestLayout<FaceLevelLayout, TValue>(procCom, comFace, masterLayout.layout_on_level(i), slaveLayout.layout_on_level(i), verbose, toPosFace, true); } } UG_LOG("Testing vertical face layouts...\n"); { FaceLayout& masterLayout = glm.get_layout<Face>(INT_V_MASTER); FaceLayout& slaveLayout = glm.get_layout<Face>(INT_V_SLAVE); int locMaxLevel = max(slaveLayout.num_levels(), masterLayout.num_levels()); int globMaxLevel = locMaxLevel; procCom.allreduce(&locMaxLevel, &globMaxLevel, 1, PCL_DT_INT, PCL_RO_MAX); for(int i = 0; i < globMaxLevel; ++i){ if(verbose){ UG_LOG("Testing FaceLayout on level " << i << ":" << endl); } bSuccess &= pcl::TestLayout<FaceLevelLayout, TValue>(procCom, comFace, masterLayout.layout_on_level(i), slaveLayout.layout_on_level(i), verbose, toPosFace, true); } } return pcl::AllProcsTrue(bSuccess); }
void CheckAssociatedEdgesOfVolumes(Grid& g) { // VOLOPT_STORE_ASSOCIATED_EDGES has to be enabled, so that this method makes sense... if(!g.option_is_enabled(VOLOPT_STORE_ASSOCIATED_EDGES)){ UG_LOG("WARNING: Autoenabling VOLOPT_STORE_ASSOCIATED_EDGES in CheckAssociatedEdgesOfVolumes.\n"); g.enable_options(VOLOPT_STORE_ASSOCIATED_EDGES); } g.begin_marking(); // iterate over all volumes for(VolumeIterator iter = g.volumes_begin(); iter != g.volumes_end(); ++iter){ Volume* vol = *iter; g.clear_marks(); // get all associated edges std::vector<Edge*> edges; CollectAssociated(edges, g, vol); // iterate over them and mark them. Make sure none is marked twice. for(size_t i = 0; i < edges.size(); ++i){ if(g.is_marked(edges[i])){ UG_THROW("Edge is contained in associated edges of volume twice!"); } g.mark(edges[i]); } // make sure that the elements have the right order, if VOLOPT_AUTOGENERATE_EDGES // or GRIDOPT_AUTOGENERATE_SIDES is active if(g.option_is_enabled(VOLOPT_AUTOGENERATE_EDGES) || g.option_is_enabled(GRIDOPT_AUTOGENERATE_SIDES)) { // edges should be sorted... // also check get_edge(vol, i)... EdgeDescriptor ed; for(size_t i_ed = 0; i_ed < vol->num_edges(); ++i_ed){ vol->edge_desc(i_ed, ed); Edge* e = g.get_edge(ed); if(e != g.get_edge(vol, i_ed)){ UG_THROW("Grid::get_edge(vol, i) does not return the i-th edge of vol!"); } if(e != edges[i_ed]){ UG_THROW("AssociatedEdges should contain edges in the correct order when autogeneration is active!"); } } } // now iterate over associated edges of all corner vertices of vol // and make sure that each is marked Volume::ConstVertexArray vrts = vol->vertices(); for(size_t i_vrt = 0; i_vrt < vol->num_vertices(); ++i_vrt){ CollectAssociated(edges, g, vrts[i_vrt]); for(size_t i_edge = 0; i_edge < edges.size(); ++i_edge){ if(VolumeContains(vol, edges[i_edge])){ if(!g.is_marked(edges[i_edge])){ UG_THROW("Edge is contained in volume but not in volume's associated-edge-container!"); } } } } } g.end_marking(); }
bool LoadPlugins(const char* pluginPath, string parentGroup, bridge::Registry& reg, bool bPrefixGroup) { PROFILE_FUNC(); typedef void (*FctInitPlugin)(ug::bridge::Registry*, string); bool bSuccess = true; // first we'll try to find all plugins in the given path vector<string> files; GetFilesInDirectory(files, pluginPath); string prefixStr = GetDynamicLibraryPrefix(); string suffixStr = string(".").append(GetDynamicLibrarySuffix()); int prefixLen = prefixStr.size(); int suffixLen = suffixStr.size(); // includes '.' for(size_t i = 0; i < files.size(); ++i){ // extract the plugins name from the file-name int nameStart = prefixLen; int nameLength = (int)files[i].size() - suffixLen - nameStart; // exclude MAC OS X hidden folder custom file ".DS_Store" from plugin consideration #ifdef __APPLE__ if(files[i].compare(".DS_Store") == 0) continue; #endif // check that plugin name can exist if(nameLength <= 0) { UG_ERR_LOG("Plugin-filename '" << files[i] << "' too short. Ignoring plugin.\n"); bSuccess = false; continue; } // check for prefix if(files[i].compare(0,prefixLen,prefixStr) != 0) { UG_ERR_LOG("Plugin-filename '" << files[i] << "' does not " "start with Plugin prefix '"<<prefixStr<<"'. Ignoring plugin.\n"); bSuccess = false; continue; } // check for suffix if(files[i].compare(files[i].size()-suffixLen,suffixLen,suffixStr) != 0) { UG_ERR_LOG("Plugin-filename '" << files[i] << "' does not " "end with Plugin suffix '"<<suffixStr<<"'. Ignoring plugin.\n"); bSuccess = false; continue; } // load the library string fullPluginName(pluginPath); fullPluginName.append("/").append(files[i]); DynLibHandle libHandle; try{ libHandle = OpenLibrary(fullPluginName.c_str()); } catch(std::string errMsg) { UG_ERR_LOG("PLUGIN-ERROR: Couldn't open plugin " << files[i] << endl); UG_ERR_LOG("Error Message: " << errMsg << "\n"); UG_ERR_LOG("NOTE: This could be due to incompatible build settings in ugshell and the plugin.\n"); bSuccess = false; continue; } // find the plugins init function string pluginName = files[i].substr(nameStart, nameLength); string fctName("InitUGPlugin_"); fctName.append(pluginName); FctInitPlugin fctInitPlugin = (FctInitPlugin) GetLibraryProcedure(libHandle, fctName.c_str()); if(!fctInitPlugin){ UG_ERR_LOG("PLUGIN-ERROR: Couldn't find entry point " << fctName << " in plugin " << files[i] << endl); CloseLibrary(libHandle); bSuccess = false; continue; } //#define DEBUG_PLUGINS #ifdef DEBUG_PLUGINS UG_LOG("Loaded plugin " << pluginName << " from " << fullPluginName << "\n"); size_t numClassesPre = reg.num_classes(); size_t numFunctionsPre = reg.num_functions(); UG_LOG("Call " << fctName << "... "); #endif // added this for better docu generation // this way, we can distinguish what plugin did what classes/functions etc. std::string group; if(bPrefixGroup) group = std::string("(Plugin) ") + pluginName + std::string(" ") + parentGroup; else group = parentGroup; // call the init method fctInitPlugin(®, group); #ifdef DEBUG_PLUGINS UG_LOG("added " << reg.num_classes() - numClassesPre << " classes, " << reg.num_functions()-numFunctionsPre << " functions, " << "group = " << group << "\n") #endif loadedPlugins.push_back(libHandle); loadedPluginNames.push_back(pluginName); } // make sure that the registry is updated reg.registry_changed(); return bSuccess; }
bool TriangleFill_SweepLine(Grid& grid, TIterator edgesBegin, TIterator edgesEnd, APosition& aPosVRT, AInt& aIntVRT, SubsetHandler* pSH, int newSubsetIndex) { if(!grid.has_vertex_attachment(aPosVRT)){ UG_LOG("position attachment missing in TriangleFill_SweepLine"); return false; } if(!grid.has_vertex_attachment(aIntVRT)){ UG_LOG("int attachment missing in TriangleFill_SweepLine"); return false; } Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPosVRT); Grid::VertexAttachmentAccessor<AInt> aaInt(grid, aIntVRT); // set up the vertex and edge arrays and build some additional // information that is required when it comes to building the triangles. std::vector<Vertex*> vrtPtrs; std::vector<vector3> vrts; std::vector<int> edges; grid.begin_marking(); for(TIterator iter = edgesBegin; iter != edgesEnd; ++iter) { Edge* e = *iter; for(size_t i = 0; i < 2; ++i){ Vertex* vrt = e->vertex(i); if(!grid.is_marked(vrt)){ aaInt[vrt] = (int)vrts.size(); vrts.push_back(aaPos[vrt]); //vrts.push_back(vector2(aaPos[vrt].x(), aaPos[vrt].y())); vrtPtrs.push_back(vrt); grid.mark(vrt); } edges.push_back(aaInt[vrt]); } } grid.end_marking(); // now call the original implementation size_t numInitialEdges = edges.size(); std::vector<int> faces; if(TriangleFill_SweepLine(faces, vrts, edges)){ // now create the triangles for(size_t i = 0; i < faces.size(); i+=3){ Triangle* tri = *grid.create<Triangle>(TriangleDescriptor(vrtPtrs[faces[i]], vrtPtrs[faces[i + 1]], vrtPtrs[faces[i + 2]])); if(pSH){ pSH->assign_subset(tri, newSubsetIndex); } } return true; } else{ //DEBUG ONLY // create edges for(size_t i = numInitialEdges; i < edges.size(); i+=2){ Edge* e = *grid.create<RegularEdge>(EdgeDescriptor(vrtPtrs[edges[i]], vrtPtrs[edges[i+1]])); if(pSH){ pSH->assign_subset(e, newSubsetIndex); } } } return false; }