void HTProcess::initializeConcreteProcess( NumLib::LocalToGlobalIndexMap const& dof_table, MeshLib::Mesh const& mesh, unsigned const integration_order) { // For the staggered scheme, both processes are assumed to use the same // element order. Therefore the order of shape function can be fetched from // any set of the sets of process variables of the coupled processes. Here, // we take the one from the first process by setting process_id = 0. const int process_id = 0; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; if (_use_monolithic_scheme) { ProcessLib::createLocalAssemblers<MonolithicHTFEM>( mesh.getDimension(), mesh.getElements(), dof_table, pv.getShapeFunctionOrder(), _local_assemblers, mesh.isAxiallySymmetric(), integration_order, *_material_properties); } else { ProcessLib::createLocalAssemblers<StaggeredHTFEM>( mesh.getDimension(), mesh.getElements(), dof_table, pv.getShapeFunctionOrder(), _local_assemblers, mesh.isAxiallySymmetric(), integration_order, *_material_properties, _heat_transport_process_id, _hydraulic_process_id); } _secondary_variables.addSecondaryVariable( "darcy_velocity", makeExtrapolator(mesh.getDimension(), getExtrapolator(), _local_assemblers, &HTLocalAssemblerInterface::getIntPtDarcyVelocity)); }
int main (int argc, char* argv[]) { LOGOG_INITIALIZE(); logog::Cout* logogCout = new logog::Cout; BaseLib::LogogSimpleFormatter* formatter = new BaseLib::LogogSimpleFormatter; logogCout->SetFormatter(*formatter); TCLAP::CmdLine cmd("Reordering of mesh nodes to make OGS Data Explorer 5 meshes compatible with OGS6.\n" \ "Method 1 is the re-ordering between DataExplorer 5 and DataExplorer 6 meshes,\n" \ "Method 2 is the re-ordering with and without InSitu-Lib in OGS6.", ' ', "0.1"); TCLAP::UnlabeledValueArg<std::string> input_mesh_arg("input_mesh", "the name of the input mesh file", true, "", "oldmesh.msh"); cmd.add(input_mesh_arg); TCLAP::UnlabeledValueArg<std::string> output_mesh_arg("output_mesh", "the name of the output mesh file", true, "", "newmesh.vtu"); cmd.add(output_mesh_arg); TCLAP::ValueArg<int> method_arg("m", "method", "reordering method selection", false, 1, "value"); cmd.add(method_arg); cmd.parse(argc, argv); MeshLib::Mesh* mesh (FileIO::readMeshFromFile(input_mesh_arg.getValue().c_str())); INFO("Reordering nodes... "); if (!method_arg.isSet() || method_arg.getValue() == 1) reorderNodes(const_cast<std::vector<MeshLib::Element*>&>(mesh->getElements())); else if (method_arg.getValue() == 2) reorderNodes2(const_cast<std::vector<MeshLib::Element*>&>(mesh->getElements())); else { ERR ("Unknown re-ordering method. Exit program..."); return 1; } FileIO::VtuInterface writer(mesh); writer.writeToFile(output_mesh_arg.getValue().c_str()); INFO("VTU file written."); delete formatter; delete logogCout; LOGOG_SHUTDOWN(); return 0; }
bool convertMeshToGeo(const MeshLib::Mesh &mesh, GeoLib::GEOObjects &geo_objects, double eps) { if (mesh.getDimension() != 2) { ERR ("Mesh to geometry conversion is only working for 2D meshes."); return false; } // nodes to points conversion std::string mesh_name(mesh.getName()); { auto points = std::make_unique<std::vector<GeoLib::Point*>>(); points->reserve(mesh.getNumberOfNodes()); for (auto node_ptr : mesh.getNodes()) points->push_back(new GeoLib::Point(*node_ptr, node_ptr->getID())); geo_objects.addPointVec(std::move(points), mesh_name, nullptr, eps); } const std::vector<std::size_t> id_map (geo_objects.getPointVecObj(mesh_name)->getIDMap()); // elements to surface triangles conversion std::string const mat_name ("MaterialIDs"); auto bounds (MeshInformation::getValueBounds<int>(mesh, mat_name)); const unsigned nMatGroups(bounds.second-bounds.first+1); auto sfcs = std::make_unique<std::vector<GeoLib::Surface*>>(); sfcs->reserve(nMatGroups); auto const& points = *geo_objects.getPointVec(mesh_name); for (unsigned i=0; i<nMatGroups; ++i) sfcs->push_back(new GeoLib::Surface(points)); const std::vector<MeshLib::Element*> &elements = mesh.getElements(); const std::size_t nElems (mesh.getNumberOfElements()); MeshLib::PropertyVector<int> const*const materialIds = mesh.getProperties().existsPropertyVector<int>("MaterialIDs") ? mesh.getProperties().getPropertyVector<int>("MaterialIDs") : nullptr; for (unsigned i=0; i<nElems; ++i) { auto surfaceId = !materialIds ? 0 : ((*materialIds)[i] - bounds.first); MeshLib::Element* e (elements[i]); if (e->getGeomType() == MeshElemType::TRIANGLE) (*sfcs)[surfaceId]->addTriangle(id_map[e->getNodeIndex(0)], id_map[e->getNodeIndex(1)], id_map[e->getNodeIndex(2)]); if (e->getGeomType() == MeshElemType::QUAD) { (*sfcs)[surfaceId]->addTriangle(id_map[e->getNodeIndex(0)], id_map[e->getNodeIndex(1)], id_map[e->getNodeIndex(2)]); (*sfcs)[surfaceId]->addTriangle(id_map[e->getNodeIndex(0)], id_map[e->getNodeIndex(2)], id_map[e->getNodeIndex(3)]); } // all other element types are ignored (i.e. lines) } std::for_each(sfcs->begin(), sfcs->end(), [](GeoLib::Surface* sfc){ if (sfc->getNumberOfTriangles()==0) delete sfc; sfc = nullptr;}); auto sfcs_end = std::remove(sfcs->begin(), sfcs->end(), nullptr); sfcs->erase(sfcs_end, sfcs->end()); geo_objects.addSurfaceVec(std::move(sfcs), mesh_name); return true; }
void HeatTransportBHEProcess::initializeConcreteProcess( NumLib::LocalToGlobalIndexMap const& dof_table, MeshLib::Mesh const& mesh, unsigned const integration_order) { // Quick access map to BHE's through element ids. std::unordered_map<std::size_t, BHE::BHETypes*> element_to_bhe_map; int const n_BHEs = _process_data._vec_BHE_property.size(); for (int i = 0; i < n_BHEs; i++) { auto const& bhe_elements = _bheMeshData.BHE_elements[i]; for (auto const& e : bhe_elements) { element_to_bhe_map[e->getID()] = &_process_data._vec_BHE_property[i]; } } assert(mesh.getDimension() == 3); ProcessLib::HeatTransportBHE::createLocalAssemblers< HeatTransportBHELocalAssemblerSoil, HeatTransportBHELocalAssemblerBHE>( mesh.getElements(), dof_table, _local_assemblers, element_to_bhe_map, mesh.isAxiallySymmetric(), integration_order, _process_data); // Create BHE boundary conditions for each of the BHEs createBHEBoundaryConditionTopBottom(_bheMeshData.BHE_nodes); }
std::size_t ElementValueModification::setByElementType(MeshLib::Mesh &mesh, MeshElemType ele_type, int const new_value) { MeshLib::PropertyVector<int>* property_value_vector = nullptr; try { property_value_vector = mesh.getProperties().getPropertyVector<int>( "MaterialIDs", MeshLib::MeshItemType::Cell, 1); } catch (std::runtime_error const& e) { ERR("%s", e.what()); return 0; } std::vector<MeshLib::Element*> const& elements(mesh.getElements()); std::size_t cnt(0); for (std::size_t k(0); k < elements.size(); k++) { if (elements[k]->getGeomType() != ele_type) { continue; } (*property_value_vector)[k] = new_value; cnt++; } return cnt; }
void LiquidFlowProcess::initializeConcreteProcess( NumLib::LocalToGlobalIndexMap const& dof_table, MeshLib::Mesh const& mesh, unsigned const integration_order) { ProcessLib::ProcessVariable const& pv = getProcessVariables()[0]; ProcessLib::createLocalAssemblers<LiquidFlowLocalAssembler>( mesh.getDimension(), mesh.getElements(), dof_table, pv.getShapeFunctionOrder(), _local_assemblers, mesh.isAxiallySymmetric(), integration_order, _gravitational_axis_id, _gravitational_acceleration, _material_properties); _secondary_variables.addSecondaryVariable( "darcy_velocity_x", 1, makeExtrapolator( getExtrapolator(), _local_assemblers, &LiquidFlowLocalAssemblerInterface::getIntPtDarcyVelocityX)); if (mesh.getDimension() > 1) { _secondary_variables.addSecondaryVariable( "darcy_velocity_y", 1, makeExtrapolator( getExtrapolator(), _local_assemblers, &LiquidFlowLocalAssemblerInterface::getIntPtDarcyVelocityY)); } if (mesh.getDimension() > 2) { _secondary_variables.addSecondaryVariable( "darcy_velocity_z", 1, makeExtrapolator( getExtrapolator(), _local_assemblers, &LiquidFlowLocalAssemblerInterface::getIntPtDarcyVelocityZ)); } }
void LayeredVolume::addLayerBoundaries(const MeshLib::Mesh &layer, std::size_t nLayers) { const unsigned nLayerBoundaries (nLayers-1); const std::size_t nNodes (layer.getNNodes()); const std::vector<MeshLib::Element*> &layer_elements (layer.getElements()); for (MeshLib::Element* elem : layer_elements) { const std::size_t nElemNodes (elem->getNBaseNodes()); for (unsigned i=0; i<nElemNodes; ++i) if (elem->getNeighbor(i) == nullptr) for (unsigned j=0; j<nLayerBoundaries; ++j) { const std::size_t offset (j*nNodes); MeshLib::Node* n0 = _nodes[offset + elem->getNodeIndex(i)]; MeshLib::Node* n1 = _nodes[offset + elem->getNodeIndex((i+1)%nElemNodes)]; MeshLib::Node* n2 = _nodes[offset + nNodes + elem->getNodeIndex((i+1)%nElemNodes)]; MeshLib::Node* n3 = _nodes[offset + nNodes + elem->getNodeIndex(i)]; if (MathLib::Vector3(*n1, *n2).getLength() > std::numeric_limits<double>::epsilon()) { const std::array<MeshLib::Node*,3> tri_nodes = {{ n0, n2, n1 }}; _elements.push_back(new MeshLib::Tri(tri_nodes, nLayers+1+j)); } if (MathLib::Vector3(*n0, *n3).getLength() > std::numeric_limits<double>::epsilon()) { const std::array<MeshLib::Node*,3> tri_nodes = {{ n0, n3, n2 }}; _elements.push_back(new MeshLib::Tri(tri_nodes, nLayers+1+j)); } } } }
void LayeredVolume::addLayerToMesh(const MeshLib::Mesh &dem_mesh, unsigned layer_id, GeoLib::Raster const& raster) { const std::size_t nNodes (dem_mesh.getNNodes()); const std::vector<MeshLib::Node*> &nodes (dem_mesh.getNodes()); const std::size_t node_id_offset (_nodes.size()); const std::size_t last_layer_node_offset (node_id_offset-nNodes); for (std::size_t i=0; i<nNodes; ++i) _nodes.push_back(getNewLayerNode(*nodes[i], *_nodes[last_layer_node_offset + i], raster, _nodes.size())); const std::vector<MeshLib::Element*> &layer_elements (dem_mesh.getElements()); for (MeshLib::Element* elem : layer_elements) { if (elem->getGeomType() == MeshLib::MeshElemType::TRIANGLE) { std::array<MeshLib::Node*,3> tri_nodes = {{ _nodes[node_id_offset+elem->getNodeIndex(0)], _nodes[node_id_offset+elem->getNodeIndex(1)], _nodes[node_id_offset+elem->getNodeIndex(2)] }}; _elements.push_back(new MeshLib::Tri(tri_nodes, layer_id)); } else if (elem->getGeomType() == MeshLib::MeshElemType::QUAD) { std::array<MeshLib::Node*,4> quad_nodes = {{ _nodes[node_id_offset+elem->getNodeIndex(0)], _nodes[node_id_offset+elem->getNodeIndex(1)], _nodes[node_id_offset+elem->getNodeIndex(2)], _nodes[node_id_offset+elem->getNodeIndex(3)] }}; _elements.push_back(new MeshLib::Quad(quad_nodes, layer_id)); } } }
std::vector<GeoLib::PointWithID*> MshEditor::getSurfaceNodes(const MeshLib::Mesh &mesh, const double *dir) { INFO ("Extracting surface nodes..."); const std::vector<MeshLib::Element*> all_elements (mesh.getElements()); const std::vector<MeshLib::Node*> all_nodes (mesh.getNodes()); std::vector<MeshLib::Element*> sfc_elements; get2DSurfaceElements(all_elements, sfc_elements, dir, mesh.getDimension()); std::vector<MeshLib::Node*> sfc_nodes; std::vector<unsigned> node_id_map(mesh.getNNodes()); get2DSurfaceNodes(all_nodes, sfc_nodes, sfc_elements, node_id_map); const unsigned nElements (sfc_elements.size()); for (unsigned i=0; i<nElements; ++i) delete sfc_elements[i]; const size_t nNodes (sfc_nodes.size()); std::vector<GeoLib::PointWithID*> surface_pnts(nNodes); for (unsigned i=0; i<nNodes; ++i) { surface_pnts[i] = new GeoLib::PointWithID(sfc_nodes[i]->getCoords(), sfc_nodes[i]->getID()); delete sfc_nodes[i]; } return surface_pnts; }
std::size_t ElementValueModification::setByElementType(MeshLib::Mesh &mesh, MeshElemType ele_type, int const new_value) { boost::optional<MeshLib::PropertyVector<int> &> optional_property_value_vec( mesh.getProperties().getPropertyVector<int>("MaterialIDs") ); if (!optional_property_value_vec) { return 0; } MeshLib::PropertyVector<int> & property_value_vector( optional_property_value_vec.get() ); std::vector<MeshLib::Element*> const& elements(mesh.getElements()); std::size_t cnt(0); for (std::size_t k(0); k<elements.size(); k++) { if (elements[k]->getGeomType()!=ele_type) continue; property_value_vector[k] = new_value; cnt++; } return cnt; }
void RichardsComponentTransportProcess::initializeConcreteProcess( NumLib::LocalToGlobalIndexMap const& dof_table, MeshLib::Mesh const& mesh, unsigned const integration_order) { const int monolithic_process_id = 0; ProcessLib::ProcessVariable const& pv = getProcessVariables(monolithic_process_id)[0]; ProcessLib::createLocalAssemblers<LocalAssemblerData>( mesh.getDimension(), mesh.getElements(), dof_table, pv.getShapeFunctionOrder(), _local_assemblers, mesh.isAxiallySymmetric(), integration_order, _process_data); _secondary_variables.addSecondaryVariable( "darcy_velocity", makeExtrapolator(mesh.getDimension(), getExtrapolator(), _local_assemblers, &RichardsComponentTransportLocalAssemblerInterface:: getIntPtDarcyVelocity)); _secondary_variables.addSecondaryVariable( "saturation", makeExtrapolator(1, getExtrapolator(), _local_assemblers, &RichardsComponentTransportLocalAssemblerInterface:: getIntPtSaturation)); }
bool MeshLayerMapper::createRasterLayers( MeshLib::Mesh const& mesh, std::vector<GeoLib::Raster const*> const& rasters, double minimum_thickness, double noDataReplacementValue) { const std::size_t nLayers(rasters.size()); if (nLayers < 2 || mesh.getDimension() != 2) { ERR("MeshLayerMapper::createRasterLayers(): A 2D mesh and at least two rasters required as input."); return false; } auto top = std::make_unique<MeshLib::Mesh>(mesh); if (!layerMapping(*top, *rasters.back(), noDataReplacementValue)) return false; auto bottom = std::make_unique<MeshLib::Mesh>(mesh); if (!layerMapping(*bottom, *rasters[0], 0)) { return false; } this->_minimum_thickness = minimum_thickness; std::size_t const nNodes = mesh.getNumberOfNodes(); _nodes.reserve(nLayers * nNodes); // number of triangles in the original mesh std::size_t const nElems (std::count_if(mesh.getElements().begin(), mesh.getElements().end(), [](MeshLib::Element const* elem) { return (elem->getGeomType() == MeshLib::MeshElemType::TRIANGLE);})); _elements.reserve(nElems * (nLayers-1)); _materials.reserve(nElems * (nLayers-1)); // add bottom layer std::vector<MeshLib::Node*> const& nodes = bottom->getNodes(); for (MeshLib::Node* node : nodes) _nodes.push_back(new MeshLib::Node(*node)); // add the other layers for (std::size_t i=0; i<nLayers-1; ++i) addLayerToMesh(*top, i, *rasters[i+1]); return true; }
void TESProcess::initializeConcreteProcess( NumLib::LocalToGlobalIndexMap const& dof_table, MeshLib::Mesh const& mesh, unsigned const integration_order) { ProcessLib::createLocalAssemblers<TESLocalAssembler>( mesh.getDimension(), mesh.getElements(), dof_table, _local_assemblers, mesh.isAxiallySymmetric(), integration_order, _assembly_params); initializeSecondaryVariables(); }
const std::pair<unsigned, unsigned> MeshInformation::getValueBounds(const MeshLib::Mesh &mesh) { const std::vector<MeshLib::Element*> &elements (mesh.getElements()); const auto minmax = std::minmax_element(elements.cbegin(), elements.cend(), [](MeshLib::Element const*const a, MeshLib::Element const*const b) { return a->getValue() < b->getValue(); }); return std::make_pair<unsigned, unsigned>((*minmax.first)->getValue(), (*minmax.second)->getValue()); }
VolumetricSourceTerm::VolumetricSourceTerm( MeshLib::Mesh const& source_term_mesh, std::unique_ptr<NumLib::LocalToGlobalIndexMap> source_term_dof_table, unsigned const integration_order, unsigned const shapefunction_order, Parameter<double> const& volumetric_source_term) : SourceTerm(std::move(source_term_dof_table)), _volumetric_source_term(volumetric_source_term) { ProcessLib::createLocalAssemblers<VolumetricSourceTermLocalAssembler>( source_term_mesh.getDimension(), source_term_mesh.getElements(), *_source_term_dof_table, shapefunction_order, _local_assemblers, source_term_mesh.isAxiallySymmetric(), integration_order, _volumetric_source_term); }
SurfaceFlux::SurfaceFlux( MeshLib::Mesh& boundary_mesh, std::size_t bulk_property_number_of_components, unsigned const integration_order) { DBUG("Create local balance assemblers."); // Populate the vector of local assemblers. _local_assemblers.resize(boundary_mesh.getElements().size()); // needed to create dof table auto mesh_subset_all_nodes = std::make_unique<MeshLib::MeshSubset>( boundary_mesh, boundary_mesh.getNodes()); // Collect the mesh subsets in a vector. std::vector<MeshLib::MeshSubset> all_mesh_subsets; std::generate_n(std::back_inserter(all_mesh_subsets), bulk_property_number_of_components, [&]() { return *mesh_subset_all_nodes; }); // needed for creation of local assemblers auto dof_table = std::make_unique<NumLib::LocalToGlobalIndexMap const>( std::move(all_mesh_subsets), NumLib::ComponentOrder::BY_LOCATION); auto const bulk_element_ids = boundary_mesh.getProperties().template getPropertyVector<std::size_t>( "bulk_element_ids", MeshLib::MeshItemType::Cell, 1); auto const bulk_face_ids = boundary_mesh.getProperties().template getPropertyVector<std::size_t>( "bulk_face_ids", MeshLib::MeshItemType::Cell, 1); ProcessLib::createLocalAssemblers<SurfaceFluxLocalAssembler>( boundary_mesh.getDimension() + 1, // or bulk_mesh.getDimension()? boundary_mesh.getElements(), *dof_table, 1, _local_assemblers, boundary_mesh.isAxiallySymmetric(), integration_order, *bulk_element_ids, *bulk_face_ids); }
void detectHoles(MeshLib::Mesh const& mesh, std::vector<std::size_t> erase_elems, std::size_t const expected_n_holes) { std::vector<MeshLib::Node*> nodes = MeshLib::copyNodeVector(mesh.getNodes()); std::vector<MeshLib::Element*> elems = MeshLib::copyElementVector(mesh.getElements(),nodes); for (auto pos : erase_elems) { delete elems[pos]; elems.erase(elems.begin()+pos); } MeshLib::Mesh mesh2("mesh2", nodes, elems); ASSERT_EQ(expected_n_holes, MeshLib::MeshValidation::detectHoles(mesh2)); };
const std::array<unsigned, 7> MeshInformation::getNumberOfElementTypes(const MeshLib::Mesh &mesh) { std::array<unsigned, 7> n_element_types = {{0, 0, 0, 0, 0, 0, 0}}; const std::vector<MeshLib::Element*> &elements (mesh.getElements()); for (auto it = elements.begin(); it != elements.end(); ++it) { MeshElemType t = (*it)->getGeomType(); if (t == MeshElemType::LINE) n_element_types[0]++; if (t == MeshElemType::TRIANGLE) n_element_types[1]++; if (t == MeshElemType::QUAD) n_element_types[2]++; if (t == MeshElemType::TETRAHEDRON) n_element_types[3]++; if (t == MeshElemType::HEXAHEDRON) n_element_types[4]++; if (t == MeshElemType::PYRAMID) n_element_types[5]++; if (t == MeshElemType::PRISM) n_element_types[6]++; } return n_element_types; }
bool LayeredVolume::createRasterLayers(const MeshLib::Mesh &mesh, const std::vector<GeoLib::Raster const*> &rasters, double minimum_thickness, double noDataReplacementValue) { if (mesh.getDimension() != 2) return false; _elevation_epsilon = calcEpsilon(*rasters[0], *rasters.back()); if (_elevation_epsilon <= 0) return false; // remove line elements, only tri + quad remain MeshLib::ElementSearch ex(mesh); ex.searchByElementType(MeshLib::MeshElemType::LINE); MeshLib::Mesh* top (removeElements(mesh, ex.getSearchedElementIDs(), "MeshLayer")); if (top==nullptr) top = new MeshLib::Mesh(mesh); if (!MeshLib::MeshLayerMapper::layerMapping(*top, *rasters.back(), noDataReplacementValue)) return false; MeshLib::Mesh* bottom (new MeshLib::Mesh(*top)); if (!MeshLib::MeshLayerMapper::layerMapping(*bottom, *rasters[0], 0)) { delete top; return false; } this->_minimum_thickness = minimum_thickness; _nodes = MeshLib::copyNodeVector(bottom->getNodes()); _elements = MeshLib::copyElementVector(bottom->getElements(), _nodes); delete bottom; // map each layer and attach to subsurface mesh const std::size_t nRasters (rasters.size()); for (std::size_t i=1; i<nRasters; ++i) this->addLayerToMesh(*top, i, *rasters[i]); // close boundaries between layers this->addLayerBoundaries(*top, nRasters); this->removeCongruentElements(nRasters, top->getNElements()); delete top; return true; }
std::vector<ElementErrorCode> MeshValidation::testElementGeometry(const MeshLib::Mesh &mesh, double min_volume) { INFO ("Testing mesh element geometry:"); const std::size_t nErrorCodes (static_cast<std::size_t>(ElementErrorFlag::MaxValue)); unsigned error_count[nErrorCodes]; std::fill_n(error_count, 4, 0); const std::size_t nElements (mesh.getNElements()); const std::vector<MeshLib::Element*> &elements (mesh.getElements()); std::vector<ElementErrorCode> error_code_vector; error_code_vector.reserve(nElements); for (std::size_t i=0; i<nElements; ++i) { const ElementErrorCode e = elements[i]->validate(); error_code_vector.push_back(e); if (e.none()) continue; // increment error statistics const std::bitset< static_cast<std::size_t>(ElementErrorFlag::MaxValue) > flags (static_cast< std::bitset<static_cast<std::size_t>(ElementErrorFlag::MaxValue)> >(e)); for (unsigned j=0; j<nErrorCodes; ++j) error_count[j] += flags[j]; } // if a larger volume threshold is given, evaluate elements again to add them even if they are formally okay if (min_volume > std::numeric_limits<double>::epsilon()) for (std::size_t i=0; i<nElements; ++i) if (elements[i]->getContent() < min_volume) error_code_vector[i].set(ElementErrorFlag::ZeroVolume); // output const unsigned error_sum (static_cast<unsigned>(std::accumulate(error_count, error_count+nErrorCodes, 0.0))); if (error_sum != 0) { ElementErrorFlag flags[nErrorCodes] = { ElementErrorFlag::ZeroVolume, ElementErrorFlag::NonCoplanar, ElementErrorFlag::NonConvex, ElementErrorFlag::NodeOrder }; for (std::size_t i=0; i<nErrorCodes; ++i) if (error_count[i]) INFO ("%d elements found with %s.", error_count[i], ElementErrorCode::toString(flags[i]).c_str()); } else INFO ("No errors found."); return error_code_vector; }
std::size_t ElementValueModification::setByElementType(MeshLib::Mesh &mesh, MeshElemType ele_type, int const new_value) { auto* const property_value_vector = mesh.getProperties().getPropertyVector<int>("MaterialIDs"); if (!property_value_vector) { return 0; } std::vector<MeshLib::Element*> const& elements(mesh.getElements()); std::size_t cnt(0); for (std::size_t k(0); k<elements.size(); k++) { if (elements[k]->getGeomType()!=ele_type) continue; (*property_value_vector)[k] = new_value; cnt++; } return cnt; }
ExtrapolationTestProcess(MeshLib::Mesh const& mesh, unsigned const integration_order) : _integration_order(integration_order), _mesh_subset_all_nodes(mesh, mesh.getNodes()) { std::vector<MeshLib::MeshSubset> all_mesh_subsets{ _mesh_subset_all_nodes}; _dof_table = std::make_unique<NumLib::LocalToGlobalIndexMap>( std::move(all_mesh_subsets), NumLib::ComponentOrder::BY_COMPONENT); // Passing _dof_table works, because this process has only one variable // and the variable has exactly one component. _extrapolator = std::make_unique<ExtrapolatorImplementation>(*_dof_table); // createAssemblers(mesh); ProcessLib::createLocalAssemblers<LocalAssemblerData>( mesh.getDimension(), mesh.getElements(), *_dof_table, 1, _local_assemblers, mesh.isAxiallySymmetric(), _integration_order); }
std::vector<GeoLib::Point*> MeshSurfaceExtraction::getSurfaceNodes(const MeshLib::Mesh &mesh, const MathLib::Vector3 &dir, double angle) { INFO ("Extracting surface nodes..."); std::vector<MeshLib::Element*> sfc_elements; get2DSurfaceElements(mesh.getElements(), sfc_elements, dir, angle, mesh.getDimension()); std::vector<MeshLib::Node*> sfc_nodes; std::vector<std::size_t> node_id_map(mesh.getNNodes()); get2DSurfaceNodes(sfc_nodes, mesh.getNNodes(), sfc_elements, node_id_map); for (auto e : sfc_elements) delete e; const std::size_t nNodes (sfc_nodes.size()); std::vector<GeoLib::Point*> surface_pnts(nNodes); for (std::size_t i=0; i<nNodes; ++i) { surface_pnts[i] = new GeoLib::Point(*(sfc_nodes[i]), sfc_nodes[i]->getID()); delete sfc_nodes[i]; } return surface_pnts; }
void PhaseFieldProcess<DisplacementDim>::initializeConcreteProcess( NumLib::LocalToGlobalIndexMap const& dof_table, MeshLib::Mesh const& mesh, unsigned const integration_order) { ProcessLib::SmallDeformation::createLocalAssemblers< DisplacementDim, PhaseFieldLocalAssembler>( mesh.getElements(), dof_table, _local_assemblers, mesh.isAxiallySymmetric(), integration_order, _process_data); _secondary_variables.addSecondaryVariable( "sigma", makeExtrapolator(MathLib::KelvinVector::KelvinVectorType< DisplacementDim>::RowsAtCompileTime, getExtrapolator(), _local_assemblers, &LocalAssemblerInterface::getIntPtSigma)); _secondary_variables.addSecondaryVariable( "epsilon", makeExtrapolator(MathLib::KelvinVector::KelvinVectorType< DisplacementDim>::RowsAtCompileTime, getExtrapolator(), _local_assemblers, &LocalAssemblerInterface::getIntPtEpsilon)); }
TEST(MeshLib, Duplicate) { MeshLib::Mesh* mesh (MeshLib::MeshGenerator::generateRegularQuadMesh(10, 5, 1)); std::vector<MeshLib::Node*> new_nodes (MeshLib::copyNodeVector(mesh->getNodes())); std::vector<MeshLib::Element*> new_elements (MeshLib::copyElementVector(mesh->getElements(), new_nodes)); MeshLib::Mesh new_mesh ("new", new_nodes, new_elements); ASSERT_EQ (mesh->getNElements(), new_mesh.getNElements()); ASSERT_EQ (mesh->getNNodes(), new_mesh.getNNodes()); std::vector<std::size_t> del_idx(1,1); MeshLib::removeMeshNodes(*mesh, del_idx); ASSERT_EQ (mesh->getNElements(), new_mesh.getNElements()-2); ASSERT_EQ (mesh->getNNodes(), new_mesh.getNNodes()-2); ASSERT_DOUBLE_EQ (4.0, MathLib::sqrDist(*mesh->getNode(0), *new_mesh.getNode(0))); ASSERT_DOUBLE_EQ (0.0, MathLib::sqrDist(*mesh->getNode(0), *new_mesh.getNode(2))); ASSERT_DOUBLE_EQ (4.0, MathLib::sqrDist(*mesh->getElement(0)->getNode(0), *new_mesh.getElement(0)->getNode(0))); ASSERT_DOUBLE_EQ (0.0, MathLib::sqrDist(*mesh->getElement(0)->getNode(0), *new_mesh.getElement(2)->getNode(0))); }
std::unique_ptr<MeshLib::Mesh> convertToLinearMesh(MeshLib::Mesh const& org_mesh, std::string const& new_mesh_name) { std::vector<MeshLib::Node*> vec_new_nodes = MeshLib::copyNodeVector(MeshLib::getBaseNodes(org_mesh.getElements())); // create new elements with the quadratic nodes std::vector<MeshLib::Element*> vec_new_eles; for (MeshLib::Element const* e : org_mesh.getElements()) { if (e->getCellType() == MeshLib::CellType::LINE3) { vec_new_eles.push_back(createLinearElement<MeshLib::Line>( e, vec_new_nodes)); } else if (e->getCellType() == MeshLib::CellType::QUAD8) { vec_new_eles.push_back(createLinearElement<MeshLib::Quad>( e, vec_new_nodes)); } else if (e->getCellType() == MeshLib::CellType::TRI6) { vec_new_eles.push_back(createLinearElement<MeshLib::Tri>( e, vec_new_nodes)); } else if (e->getCellType() == MeshLib::CellType::HEX20) { vec_new_eles.push_back(createLinearElement<MeshLib::Hex>( e, vec_new_nodes)); } else if (e->getCellType() == MeshLib::CellType::TET10) { vec_new_eles.push_back(createLinearElement<MeshLib::Tet>( e, vec_new_nodes)); } else { OGS_FATAL("Mesh element type %s is not supported", MeshLib::CellType2String(e->getCellType()).c_str()); } } auto new_mesh = std::make_unique<MeshLib::Mesh>( new_mesh_name, vec_new_nodes, vec_new_eles, org_mesh.getProperties().excludeCopyProperties( std::vector<MeshLib::MeshItemType>(1, MeshLib::MeshItemType::Node))); // copy property vectors for nodes MeshLib::Properties const& src_properties = org_mesh.getProperties(); for (auto name : src_properties.getPropertyVectorNames()) { if (!src_properties.existsPropertyVector<double>(name)) { continue; } auto const* src_prop = src_properties.getPropertyVector<double>(name); if (src_prop->getMeshItemType() != MeshLib::MeshItemType::Node) { continue; } auto const n_src_comp = src_prop->getNumberOfComponents(); auto new_prop = new_mesh->getProperties().createNewPropertyVector<double>( name, MeshLib::MeshItemType::Node, n_src_comp); new_prop->resize(new_mesh->getNumberOfNodes() * n_src_comp); // copy only base node values for (unsigned i=0; i<org_mesh.getNumberOfBaseNodes(); i++) { for (int j = 0; j < n_src_comp; j++) { (*new_prop)[i * n_src_comp + j] = (*src_prop)[i * n_src_comp + j]; } } } return new_mesh; }
std::unique_ptr<MeshLib::Mesh> appendLinesAlongPolylines( const MeshLib::Mesh& mesh, const GeoLib::PolylineVec& ply_vec) { // copy existing nodes and elements std::vector<MeshLib::Node*> vec_new_nodes = MeshLib::copyNodeVector(mesh.getNodes()); std::vector<MeshLib::Element*> vec_new_eles = MeshLib::copyElementVector(mesh.getElements(), vec_new_nodes); auto const material_ids = materialIDs(mesh); int const max_matID = material_ids ? *(std::max_element(begin(*material_ids), end(*material_ids))) : 0; std::vector<int> new_mat_ids; const std::size_t n_ply (ply_vec.size()); // for each polyline for (std::size_t k(0); k < n_ply; k++) { const GeoLib::Polyline* ply = (*ply_vec.getVector())[k]; // search nodes on the polyline MeshGeoToolsLib::MeshNodesAlongPolyline mshNodesAlongPoly( mesh, *ply, mesh.getMinEdgeLength() * 0.5, MeshGeoToolsLib::SearchAllNodes::Yes); auto &vec_nodes_on_ply = mshNodesAlongPoly.getNodeIDs(); if (vec_nodes_on_ply.empty()) { std::string ply_name; ply_vec.getNameOfElementByID(k, ply_name); INFO("No nodes found on polyline %s", ply_name.c_str()); continue; } // add line elements for (std::size_t i=0; i<vec_nodes_on_ply.size()-1; i++) { std::array<MeshLib::Node*, 2> element_nodes; element_nodes[0] = vec_new_nodes[vec_nodes_on_ply[i]]; element_nodes[1] = vec_new_nodes[vec_nodes_on_ply[i+1]]; vec_new_eles.push_back( new MeshLib::Line(element_nodes, vec_new_eles.size())); new_mat_ids.push_back(max_matID+k+1); } } // generate a mesh const std::string name = mesh.getName() + "_with_lines"; auto new_mesh = std::make_unique<MeshLib::Mesh>(name, vec_new_nodes, vec_new_eles); auto new_material_ids = new_mesh->getProperties().createNewPropertyVector<int>( "MaterialIDs", MeshLib::MeshItemType::Cell); if (!new_material_ids) { OGS_FATAL("Could not create MaterialIDs cell vector in new mesh."); } new_material_ids->reserve(new_mesh->getNumberOfElements()); if (material_ids != nullptr) { std::copy(begin(*material_ids), end(*material_ids), std::back_inserter(*new_material_ids)); } else { new_material_ids->resize(mesh.getNumberOfElements()); } std::copy(begin(new_mat_ids), end(new_mat_ids), std::back_inserter(*new_material_ids)); return new_mesh; }
void getFractureMatrixDataInMesh( MeshLib::Mesh const& mesh, std::vector<MeshLib::Element*>& vec_matrix_elements, std::vector<MeshLib::Element*>& vec_fracture_elements, std::vector<MeshLib::Element*>& vec_fracture_matrix_elements, std::vector<MeshLib::Node*>& vec_fracture_nodes ) { IsCrackTip isCrackTip(mesh); // get vectors of matrix elements and fracture elements vec_matrix_elements.reserve(mesh.getNumberOfElements()); for (MeshLib::Element* e : mesh.getElements()) { if (e->getDimension() == mesh.getDimension()) vec_matrix_elements.push_back(e); else vec_fracture_elements.push_back(e); } DBUG("-> found total %d matrix elements and %d fracture elements", vec_matrix_elements.size(), vec_fracture_elements.size()); // get a vector of fracture nodes for (MeshLib::Element* e : vec_fracture_elements) { for (unsigned i=0; i<e->getNumberOfNodes(); i++) { if (isCrackTip(*e->getNode(i))) continue; vec_fracture_nodes.push_back(const_cast<MeshLib::Node*>(e->getNode(i))); } } std::sort(vec_fracture_nodes.begin(), vec_fracture_nodes.end(), [](MeshLib::Node* node1, MeshLib::Node* node2) { return (node1->getID() < node2->getID()); } ); vec_fracture_nodes.erase( std::unique(vec_fracture_nodes.begin(), vec_fracture_nodes.end()), vec_fracture_nodes.end()); DBUG("-> found %d nodes on the fracture", vec_fracture_nodes.size()); // create a vector fracture elements and connected matrix elements, // which are passed to a DoF table // first, collect matrix elements for (MeshLib::Element *e : vec_fracture_elements) { for (unsigned i=0; i<e->getNumberOfBaseNodes(); i++) { MeshLib::Node const* node = e->getNode(i); if (isCrackTip(*node)) continue; for (unsigned j=0; j<node->getNumberOfElements(); j++) { // only matrix elements if (node->getElement(j)->getDimension() == mesh.getDimension()-1) continue; vec_fracture_matrix_elements.push_back(const_cast<MeshLib::Element*>(node->getElement(j))); } } } std::sort(vec_fracture_matrix_elements.begin(), vec_fracture_matrix_elements.end(), [](MeshLib::Element* p1, MeshLib::Element* p2) { return (p1->getID() < p2->getID()); } ); vec_fracture_matrix_elements.erase( std::unique(vec_fracture_matrix_elements.begin(), vec_fracture_matrix_elements.end()), vec_fracture_matrix_elements.end()); // second, append fracture elements vec_fracture_matrix_elements.insert( vec_fracture_matrix_elements.end(), vec_fracture_elements.begin(), vec_fracture_elements.end()); }
TEST(MeshLib, ElementStatus) { const unsigned width (100); const unsigned elements_per_side (20); MeshLib::Mesh* mesh (MeshLib::MeshGenerator::generateRegularQuadMesh(width, elements_per_side)); MeshLib::ElementStatus status(mesh); const std::vector<MeshLib::Element*> elements (mesh->getElements()); for (unsigned i=0; i<elements_per_side; ++i) { for (unsigned j=0; j<elements_per_side; ++j) elements[i*elements_per_side + j]->setValue(i); } // all elements active ASSERT_EQ (elements.size(), status.getNActiveElements()); // all nodes active ASSERT_EQ (mesh->getNNodes(), status.getNActiveNodes()); // set material 1 to false status.setMaterialStatus(1, false); ASSERT_EQ (elements.size()-elements_per_side, status.getNActiveElements()); // set material 1 to false (again) status.setMaterialStatus(1, false); ASSERT_EQ (elements.size()-elements_per_side, status.getNActiveElements()); // set material 0 to false status.setMaterialStatus(0, false); ASSERT_EQ (elements.size()-(2*elements_per_side), status.getNActiveElements()); // active elements std::vector<std::size_t> active_elements (status.getActiveElements()); ASSERT_EQ (active_elements.size(), status.getNActiveElements()); // active nodes std::vector<std::size_t> active_nodes (status.getActiveNodes()); ASSERT_EQ (active_nodes.size(), status.getNActiveNodes()); // set element 1 to false (yet again) status.setElementStatus(1, false); status.getElementStatus(1); ASSERT_EQ (elements.size()-(2*elements_per_side), status.getNActiveElements()); ASSERT_EQ (mesh->getNNodes()-(2*(elements_per_side+1)), status.getNActiveNodes()); // set element 1 to true status.setElementStatus(1, true); ASSERT_EQ (elements.size()-(2*elements_per_side)+1, status.getNActiveElements()); ASSERT_EQ (mesh->getNNodes()-(2*(elements_per_side+1))+4, status.getNActiveNodes()); ASSERT_EQ(status.getElementStatus(1), true); std::vector<std::size_t> active_elements_at_node (status.getActiveElementsAtNode(2)); ASSERT_EQ(1u, active_elements_at_node.size()); active_elements_at_node = status.getActiveElementsAtNode(22); ASSERT_EQ(1u, active_elements_at_node.size()); active_elements_at_node = status.getActiveElementsAtNode(44); ASSERT_EQ(2u, active_elements_at_node.size()); active_elements_at_node = status.getActiveElementsAtNode(102); ASSERT_EQ(4u, active_elements_at_node.size()); status.setAll(true); ASSERT_EQ(elements.size(), status.getNActiveElements()); ASSERT_EQ(mesh->getNNodes(), status.getNActiveNodes()); status.setAll(false); ASSERT_EQ(0u, status.getNActiveElements()); ASSERT_EQ(0u, status.getNActiveNodes()); }
PostProcessTool::PostProcessTool( MeshLib::Mesh const& org_mesh, std::vector<MeshLib::Node*> const& vec_fracture_nodes, std::vector<MeshLib::Element*> const& vec_fracutre_matrix_elements) :_org_mesh(org_mesh) { if (!org_mesh.getProperties().hasPropertyVector("displacement") || !org_mesh.getProperties().hasPropertyVector("displacement_jump1") || !org_mesh.getProperties().hasPropertyVector("levelset1") ) { OGS_FATAL("The given mesh does not have relevant properties"); } // clone nodes and elements std::vector<MeshLib::Node*> new_nodes(MeshLib::copyNodeVector(org_mesh.getNodes())); std::vector<MeshLib::Element*> new_eles( MeshLib::copyElementVector(org_mesh.getElements(), new_nodes)); // duplicate fracture nodes for (auto const* org_node : vec_fracture_nodes) { auto duplicated_node = new MeshLib::Node(org_node->getCoords(), new_nodes.size()); new_nodes.push_back(duplicated_node); _map_dup_newNodeIDs[org_node->getID()] = duplicated_node->getID(); } // split elements using the new duplicated nodes auto prop_levelset = org_mesh.getProperties().getPropertyVector<double>("levelset1"); for (auto const* org_e : vec_fracutre_matrix_elements) { // only matrix elements if (org_e->getDimension() != org_mesh.getDimension()) continue; auto const eid = org_e->getID(); // keep original if the element has levelset=0 if ((*prop_levelset)[eid] == 0) continue; // replace fracture nodes with duplicated ones MeshLib::Element* e = new_eles[eid]; for (unsigned i=0; i<e->getNumberOfNodes(); i++) { // only fracture nodes auto itr = _map_dup_newNodeIDs.find(e->getNodeIndex(i)); if (itr == _map_dup_newNodeIDs.end()) continue; // check if a node belongs to the particular fracture group auto itr2 = std::find_if(vec_fracture_nodes.begin(), vec_fracture_nodes.end(), [&](MeshLib::Node const*node) { return node->getID()==e->getNodeIndex(i);}); if (itr2 == vec_fracture_nodes.end()) continue; e->setNode(i, new_nodes[itr->second]); } } // new mesh _output_mesh.reset(new MeshLib::Mesh(org_mesh.getName(), new_nodes, new_eles)); createProperties<int>(); createProperties<double>(); copyProperties<int>(); copyProperties<double>(); calculateTotalDisplacement(); }