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))); }
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(); }
MeshLib::Mesh* MeshLayerMapper::createStaticLayers(MeshLib::Mesh const& mesh, std::vector<float> const& layer_thickness_vector, std::string const& mesh_name) { std::vector<float> thickness; for (std::size_t i=0; i<layer_thickness_vector.size(); ++i) if (layer_thickness_vector[i] > std::numeric_limits<float>::epsilon()) thickness.push_back(layer_thickness_vector[i]); else WARN ("Ignoring layer %d with thickness %f.", i, layer_thickness_vector[i]); const std::size_t nLayers(thickness.size()); if (nLayers < 1 || mesh.getDimension() != 2) { ERR("MeshLayerMapper::createStaticLayers(): A 2D mesh with nLayers > 0 is required as input."); return nullptr; } const std::size_t nNodes = mesh.getNumberOfNodes(); // count number of 2d elements in the original mesh const std::size_t nElems (std::count_if(mesh.getElements().begin(), mesh.getElements().end(), [](MeshLib::Element const* elem) { return (elem->getDimension() == 2);})); const std::size_t nOrgElems (mesh.getNumberOfElements()); const std::vector<MeshLib::Node*> &nodes = mesh.getNodes(); const std::vector<MeshLib::Element*> &elems = mesh.getElements(); std::vector<MeshLib::Node*> new_nodes(nNodes + (nLayers * nNodes)); std::vector<MeshLib::Element*> new_elems; new_elems.reserve(nElems * nLayers); MeshLib::Properties properties; auto* const materials = properties.createNewPropertyVector<int>( "MaterialIDs", MeshLib::MeshItemType::Cell); if (!materials) { ERR("Could not create PropertyVector object 'MaterialIDs'."); return nullptr; } materials->reserve(nElems * nLayers); double z_offset (0.0); for (unsigned layer_id = 0; layer_id <= nLayers; ++layer_id) { // add nodes for new layer unsigned node_offset (nNodes * layer_id); if (layer_id > 0) z_offset += thickness[layer_id-1]; std::transform(nodes.cbegin(), nodes.cend(), new_nodes.begin() + node_offset, [&z_offset](MeshLib::Node* node){ return new MeshLib::Node((*node)[0], (*node)[1], (*node)[2]-z_offset); }); // starting with 2nd layer create prism or hex elements connecting the last layer with the current one if (layer_id == 0) continue; node_offset -= nNodes; const unsigned mat_id (nLayers - layer_id); for (unsigned i = 0; i < nOrgElems; ++i) { const MeshLib::Element* sfc_elem( elems[i] ); if (sfc_elem->getDimension() < 2) // ignore line-elements continue; const unsigned nElemNodes(sfc_elem->getNumberOfBaseNodes()); auto** e_nodes = new MeshLib::Node*[2 * nElemNodes]; for (unsigned j=0; j<nElemNodes; ++j) { const unsigned node_id = sfc_elem->getNode(j)->getID() + node_offset; e_nodes[j] = new_nodes[node_id+nNodes]; e_nodes[j+nElemNodes] = new_nodes[node_id]; } if (sfc_elem->getGeomType() == MeshLib::MeshElemType::TRIANGLE) { // extrude triangles to prism new_elems.push_back(new MeshLib::Prism(e_nodes)); } else if (sfc_elem->getGeomType() == MeshLib::MeshElemType::QUAD) { // extrude quads to hexes new_elems.push_back(new MeshLib::Hex(e_nodes)); } else { OGS_FATAL("MeshLayerMapper: Unknown element type to extrude."); } materials->push_back(mat_id); } } return new MeshLib::Mesh(mesh_name, new_nodes, new_elems, properties); }
void Caller::create_node_calls(const NodePileup& np) { int n = _node->sequence().length(); const string& seq = _node->sequence(); int cur = 0; int cat = call_cat(_node_calls[cur]); NodePair prev_nodes(-1, -1); // scan contiguous chunks of a node with same call // (note: snps will always be 1-base -- never merged) for (int next = 1; next <= n; ++next) { int next_cat = next == n ? -1 : call_cat(_node_calls[next]); if (cat == 2 || cat != next_cat) { NodePair new_nodes(-1, -1); bool secondary_snp = false; // process first genotype if it's not missing if (_node_calls[cur].first == '.') { // add single node for stretch of reference node string new_seq = seq.substr(cur, next - cur); new_nodes.first = ++_max_id; _call_graph.create_node(new_seq, new_nodes.first); } else if (_node_calls[cur].first != '-') { // add snp node assert(next - cur == 1); string new_seq(1, _node_calls[cur].first); new_nodes.first = ++_max_id; _call_graph.create_node(new_seq, new_nodes.first); create_snp_path(new_nodes.first, secondary_snp); secondary_snp = true; } // process second genotype if difference from first if (_node_calls[cur].second != _node_calls[cur].first) { if (_node_calls[cur].second == '.') { // add single node for stretch of reference node string new_seq = seq.substr(cur, next - cur); new_nodes.second = ++_max_id; _call_graph.create_node(new_seq, new_nodes.second); } else if (_node_calls[cur].second != '-') { // add snp node assert(next - cur == 1); string new_seq(1, _node_calls[cur].second); new_nodes.second = ++_max_id; _call_graph.create_node(new_seq, new_nodes.second); create_snp_path(new_nodes.second, secondary_snp); } } // update maps if new node abuts end of original node // so that edges can be updated later on: if (new_nodes.first != -1 || new_nodes.second != -1) { if (cur == 0) { _start_node_map[_node->id()] = new_nodes; } if (next == n) { _end_node_map[_node->id()] = new_nodes; } } // add edges if (prev_nodes.first != -1 && new_nodes.first != -1) { _call_graph.create_edge(prev_nodes.first, new_nodes.first); } if (prev_nodes.first != -1 && new_nodes.second != -1) { _call_graph.create_edge(prev_nodes.first, new_nodes.second); } if (prev_nodes.second != -1 && new_nodes.first != -1) { _call_graph.create_edge(prev_nodes.second, new_nodes.first); } if (prev_nodes.second != -1 && new_nodes.second != -1) { _call_graph.create_edge(prev_nodes.second, new_nodes.second); } // shift right cur = next; cat = next_cat; prev_nodes = new_nodes; } } }