int main (int argc, char* argv[]) { ApplicationsLib::LogogSetup logog_setup; TCLAP::CmdLine cmd( "Creates a new file for material properties and sets the material ids " "in the msh-file to 0\n\n" "OpenGeoSys-6 software, version " + BaseLib::BuildInfo::git_describe + ".\n" "Copyright (c) 2012-2019, OpenGeoSys Community " "(http://www.opengeosys.org)", ' ', BaseLib::BuildInfo::git_describe); TCLAP::ValueArg<std::string> mesh_arg("m", "mesh", "the mesh to open from a file", false, "", "filename for mesh input"); cmd.add( mesh_arg ); cmd.parse( argc, argv ); // read mesh std::unique_ptr<MeshLib::Mesh> mesh( MeshLib::IO::readMeshFromFile(mesh_arg.getValue())); if (!mesh) { INFO("Could not read mesh from file '%s'.", mesh_arg.getValue().c_str()); return EXIT_FAILURE; } auto const materialIds = materialIDs(*mesh); if (!materialIds) { OGS_FATAL("Mesh contains no int-property vector named 'MaterialIDs'."); } std::size_t const n_properties(materialIds->size()); assert(n_properties != mesh->getNumberOfElements()); std::string const name = BaseLib::extractBaseNameWithoutExtension(mesh_arg.getValue()); // create file std::string const new_matname(name + "_prop"); std::ofstream out_prop(new_matname.c_str(), std::ios::out); if (out_prop.is_open()) { for (std::size_t i = 0; i < n_properties; ++i) { out_prop << i << "\t" << (*materialIds)[i] << "\n"; } out_prop.close(); } else { ERR("Could not create property '%s' file.", new_matname.c_str()); return EXIT_FAILURE; } mesh->getProperties().removePropertyVector("MaterialIDs"); std::string const new_mshname(name + "_new.vtu"); INFO("Writing mesh to file '%s'.", new_mshname.c_str()); MeshLib::IO::writeMeshToFile(*mesh, new_mshname); INFO("New files '%s' and '%s' written.", new_mshname.c_str(), new_matname.c_str()); return EXIT_SUCCESS; }
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; }
std::unique_ptr<Process> createSmallDeformationProcess( MeshLib::Mesh& mesh, std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler, std::vector<ProcessVariable> const& variables, std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters, boost::optional<ParameterLib::CoordinateSystem> const& local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const& config) { //! \ogs_file_param{prj__processes__process__type} config.checkConfigParameter("type", "SMALL_DEFORMATION_WITH_LIE"); DBUG("Create SmallDeformationProcess with LIE."); // Process variables //! \ogs_file_param{prj__processes__process__SMALL_DEFORMATION_WITH_LIE__process_variables} auto const pv_conf = config.getConfigSubtree("process_variables"); auto range = //! \ogs_file_param{prj__processes__process__SMALL_DEFORMATION_WITH_LIE__process_variables__process_variable} pv_conf.getConfigParameterList<std::string>("process_variable"); std::vector<std::reference_wrapper<ProcessVariable>> per_process_variables; std::size_t n_var_du = 0; for (std::string const& pv_name : range) { if (pv_name != "displacement" && pv_name.find("displacement_jump") != 0) { OGS_FATAL( "Found a process variable name '%s'. It should be " "'displacement' or 'displacement_jumpN' or " "'displacement_junctionN'"); } if (pv_name.find("displacement_jump") == 0) { n_var_du++; } auto variable = std::find_if(variables.cbegin(), variables.cend(), [&pv_name](ProcessVariable const& v) { return v.getName() == pv_name; }); if (variable == variables.end()) { OGS_FATAL( "Could not find process variable '%s' in the provided " "variables " "list for config tag <%s>.", pv_name.c_str(), "process_variable"); } DBUG("Found process variable '%s' for config tag <%s>.", variable->getName().c_str(), "process_variable"); per_process_variables.emplace_back( const_cast<ProcessVariable&>(*variable)); } if (n_var_du < 1) { OGS_FATAL("No displacement jump variables are specified"); } DBUG("Associate displacement with process variable '%s'.", per_process_variables.back().get().getName().c_str()); if (per_process_variables.back().get().getNumberOfComponents() != DisplacementDim) { OGS_FATAL( "Number of components of the process variable '%s' is different " "from the displacement dimension: got %d, expected %d", per_process_variables.back().get().getName().c_str(), per_process_variables.back().get().getNumberOfComponents(), DisplacementDim); } std::vector<std::vector<std::reference_wrapper<ProcessVariable>>> process_variables; process_variables.push_back(std::move(per_process_variables)); auto solid_constitutive_relations = MaterialLib::Solids::createConstitutiveRelations<DisplacementDim>( parameters, local_coordinate_system, config); // Fracture constitutive relation. // read type; auto const fracture_model_config = //! \ogs_file_param{prj__processes__process__SMALL_DEFORMATION_WITH_LIE__fracture_model} config.getConfigSubtree("fracture_model"); auto const frac_type = //! \ogs_file_param{prj__processes__process__SMALL_DEFORMATION_WITH_LIE__fracture_model__type} fracture_model_config.peekConfigParameter<std::string>("type"); std::unique_ptr<MaterialLib::Fracture::FractureModelBase<DisplacementDim>> fracture_model = nullptr; if (frac_type == "LinearElasticIsotropic") { fracture_model = MaterialLib::Fracture::createLinearElasticIsotropic< DisplacementDim>(parameters, fracture_model_config); } else if (frac_type == "MohrCoulomb") { fracture_model = MaterialLib::Fracture::createMohrCoulomb<DisplacementDim>( parameters, fracture_model_config); } else if (frac_type == "CohesiveZoneModeI") { fracture_model = MaterialLib::Fracture::CohesiveZoneModeI::createCohesiveZoneModeI< DisplacementDim>(parameters, fracture_model_config); } else { OGS_FATAL( "Cannot construct fracture constitutive relation of given type " "'%s'.", frac_type.c_str()); } // Fracture properties std::vector<FractureProperty> fracture_properties; for ( auto fracture_properties_config : //! \ogs_file_param{prj__processes__process__SMALL_DEFORMATION_WITH_LIE__fracture_properties} config.getConfigSubtreeList("fracture_properties")) { fracture_properties.emplace_back( fracture_properties.size(), //! \ogs_file_param{prj__processes__process__SMALL_DEFORMATION_WITH_LIE__fracture_properties__material_id} fracture_properties_config.getConfigParameter<int>("material_id"), ParameterLib::findParameter<double>( //! \ogs_file_param_special{prj__processes__process__SMALL_DEFORMATION_WITH_LIE__fracture_properties__initial_aperture} fracture_properties_config, "initial_aperture", parameters, 1)); } if (n_var_du < fracture_properties.size()) { OGS_FATAL( "The number of displacement jumps and the number of " "<fracture_properties> " "are not consistent"); } // Reference temperature const auto& reference_temperature = //! \ogs_file_param{prj__processes__process__SMALL_DEFORMATION_WITH_LIE__reference_temperature} config.getConfigParameter<double>( "reference_temperature", std::numeric_limits<double>::quiet_NaN()); SmallDeformationProcessData<DisplacementDim> process_data( materialIDs(mesh), std::move(solid_constitutive_relations), std::move(fracture_model), std::move(fracture_properties), reference_temperature); SecondaryVariableCollection secondary_variables; NumLib::NamedFunctionCaller named_function_caller( {"SmallDeformation_displacement"}); ProcessLib::createSecondaryVariables(config, secondary_variables, named_function_caller); return std::make_unique<SmallDeformationProcess<DisplacementDim>>( mesh, std::move(jacobian_assembler), parameters, integration_order, std::move(process_variables), std::move(process_data), std::move(secondary_variables), std::move(named_function_caller)); }
std::unique_ptr<Process> createTwoPhaseFlowWithPPProcess( MeshLib::Mesh& mesh, std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler, std::vector<ProcessVariable> const& variables, std::vector<std::unique_ptr<ParameterBase>> const& parameters, unsigned const integration_order, BaseLib::ConfigTree const& config, std::map<std::string, std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const& curves) { //! \ogs_file_param{prj__processes__process__type} config.checkConfigParameter("type", "TWOPHASE_FLOW_PP"); DBUG("Create TwoPhaseFlowProcess with PP model."); //! \ogs_file_param{prj__processes__process__TWOPHASE_FLOW_PP__process_variables} auto const pv_config = config.getConfigSubtree("process_variables"); auto per_process_variables = findProcessVariables( variables, pv_config, {//! \ogs_file_param_special{prj__processes__process__TWOPHASE_FLOW_PP__process_variables__gas_pressure} "gas_pressure", //! \ogs_file_param_special{prj__processes__process__TWOPHASE_FLOW_PP__process_variables__capillary_pressure} "capillary_pressure"}); std::vector<std::vector<std::reference_wrapper<ProcessVariable>>> process_variables; process_variables.push_back(std::move(per_process_variables)); SecondaryVariableCollection secondary_variables; NumLib::NamedFunctionCaller named_function_caller( {"TwoPhaseFlow_pressure"}); ProcessLib::createSecondaryVariables(config, secondary_variables, named_function_caller); // Specific body force std::vector<double> const b = //! \ogs_file_param{prj__processes__process__TWOPHASE_FLOW_PP__specific_body_force} config.getConfigParameter<std::vector<double>>("specific_body_force"); assert(!b.empty() && b.size() < 4); Eigen::VectorXd specific_body_force(b.size()); bool const has_gravity = MathLib::toVector(b).norm() > 0; if (has_gravity) std::copy_n(b.data(), b.size(), specific_body_force.data()); //! \ogs_file_param{prj__processes__process__TWOPHASE_FLOW_PP__mass_lumping} auto const mass_lumping = config.getConfigParameter<bool>("mass_lumping"); auto& temperature = findParameter<double>( config, //! \ogs_file_param_special{prj__processes__process__TWOPHASE_FLOW_PP__temperature} "temperature", parameters, 1); //! \ogs_file_param{prj__processes__process__TWOPHASE_FLOW_PP__material_property} auto const& mat_config = config.getConfigSubtree("material_property"); auto const material_ids = materialIDs(mesh); if (material_ids) { INFO("The twophase flow is in heterogeneous porous media."); } else { INFO("The twophase flow is in homogeneous porous media."); } std::unique_ptr<TwoPhaseFlowWithPPMaterialProperties> material = createTwoPhaseFlowWithPPMaterialProperties(mat_config, material_ids, parameters); TwoPhaseFlowWithPPProcessData process_data{ specific_body_force, has_gravity, mass_lumping, temperature, std::move(material)}; return std::make_unique<TwoPhaseFlowWithPPProcess>( mesh, std::move(jacobian_assembler), parameters, integration_order, std::move(process_variables), std::move(process_data), std::move(secondary_variables), std::move(named_function_caller), mat_config, curves); }
int main(int argc, char *argv[]) { ApplicationsLib::LogogSetup logog_setup; TCLAP::CmdLine cmd( "Query mesh information.\n\n" "OpenGeoSys-6 software, version " + BaseLib::BuildInfo::git_describe + ".\n" "Copyright (c) 2012-2019, OpenGeoSys Community " "(http://www.opengeosys.org)", ' ', BaseLib::BuildInfo::git_describe); TCLAP::UnlabeledValueArg<std::string> mesh_arg("mesh-file","input mesh file",true,"","string"); cmd.add( mesh_arg ); TCLAP::MultiArg<std::size_t> eleId_arg("e","element-id","element ID",false,"number"); cmd.add( eleId_arg ); TCLAP::MultiArg<std::size_t> nodeId_arg("n","node-id","node ID",false,"number"); cmd.add( nodeId_arg ); TCLAP::SwitchArg showNodeWithMaxEle_arg("", "show-node-with-max-elements", "show a node having the max number of connected elements", false); cmd.add( showNodeWithMaxEle_arg ); cmd.parse( argc, argv ); const std::string filename(mesh_arg.getValue()); // read the mesh file auto const mesh = std::unique_ptr<MeshLib::Mesh>( MeshLib::IO::readMeshFromFile(filename)); if (!mesh) { return EXIT_FAILURE; } std::vector<std::size_t> selected_node_ids; if (showNodeWithMaxEle_arg.getValue()) { auto itr = std::max_element(mesh->getNodes().begin(), mesh->getNodes().end(), [](MeshLib::Node* i, MeshLib::Node* j) { return i->getNumberOfElements() < j->getNumberOfElements(); }); if (itr != mesh->getNodes().end()) { MeshLib::Node* node = *itr; selected_node_ids.push_back(node->getID()); } } selected_node_ids.insert(selected_node_ids.end(), nodeId_arg.getValue().begin(), nodeId_arg.getValue().end()); auto const materialIds = materialIDs(*mesh); for (auto ele_id : eleId_arg.getValue()) { std::stringstream out; out << std::scientific << std::setprecision(std::numeric_limits<double>::digits10); out << "--------------------------------------------------------" << std::endl; auto* ele = mesh->getElement(ele_id); out << "# Element " << ele->getID() << std::endl; out << "Type : " << CellType2String(ele->getCellType()) << std::endl; if (materialIds) { out << "Mat ID : " << (*materialIds)[ele_id] << std::endl; } out << "Nodes: " << std::endl; for (unsigned i = 0; i < ele->getNumberOfNodes(); i++) { out << ele->getNode(i)->getID() << " " << *ele->getNode(i) << std::endl; } out << "Content: " << ele->getContent() << std::endl; out << "Neighbors: "; for (unsigned i=0; i<ele->getNumberOfNeighbors(); i++) { if (ele->getNeighbor(i)) { out << ele->getNeighbor(i)->getID() << " "; } else { out << "none "; } } out << std::endl; INFO("%s", out.str().c_str()); } for (auto node_id : selected_node_ids) { std::stringstream out; out << std::scientific << std::setprecision(std::numeric_limits<double>::digits10); out << "--------------------------------------------------------" << std::endl; MeshLib::Node const* node = mesh->getNode(node_id); out << "# Node " << node->getID() << std::endl; out << "Coordinates: " << *node << std::endl; out << "Connected elements (" << node->getNumberOfElements() << "): "; for (auto ele : node->getElements()) { out << ele->getID() << " "; } out << std::endl; out << "Connected nodes (" << node->getConnectedNodes().size() << "): "; for (auto nd : node->getConnectedNodes()) { out << nd->getID() << " "; } out << std::endl; INFO("%s", out.str().c_str()); } }