diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c7370ffabb..401d60937e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,10 @@ jobs: pkg-config `# for installing libraries with vcpkg`\ git \ cmake \ - ninja-build + ninja-build \ + libfontconfig1-dev `# From here required for vcpkg opencascade`\ + libx11-dev \ + libgl-dev - uses: hendrikmuhs/ccache-action@v1.2 with: @@ -61,15 +64,17 @@ jobs: simbody \ gtest \ xsimd \ - pybind11 + pybind11 \ + opencascade - name: Generate buildsystem using float (No test) run: | cmake -G Ninja \ -D CMAKE_BUILD_TYPE=Release \ - -D SPHINXSYS_USE_FLOAT=ON \ -D CMAKE_TOOLCHAIN_FILE="${{github.workspace}}/vcpkg/scripts/buildsystems/vcpkg.cmake" \ -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -D SPHINXSYS_USE_FLOAT=ON \ + -D SPHINXSYS_MODULE_OPENCASCADE=ON \ -D SPHINXSYS_CI=ON \ -S ${{github.workspace}} \ -B ${{github.workspace}}/build @@ -97,7 +102,10 @@ jobs: pkg-config `# for installing libraries with vcpkg`\ git \ cmake \ - ninja-build + ninja-build \ + libfontconfig1-dev `# From here required for vcpkg opencascade`\ + libx11-dev \ + libgl-dev - uses: hendrikmuhs/ccache-action@v1.2 with: @@ -121,16 +129,18 @@ jobs: simbody \ gtest \ xsimd \ - pybind11 + pybind11 \ + opencascade - name: Generate buildsystem using double run: | cmake -G Ninja \ -D CMAKE_BUILD_TYPE=Release \ - -D SPHINXSYS_USE_FLOAT=OFF \ -D CMAKE_TOOLCHAIN_FILE="${{github.workspace}}/vcpkg/scripts/buildsystems/vcpkg.cmake" \ -D CMAKE_C_COMPILER_LAUNCHER=ccache -D CMAKE_CXX_COMPILER_LAUNCHER=ccache \ -D SPHINXSYS_CI=ON \ + -D SPHINXSYS_USE_FLOAT=OFF \ + -D SPHINXSYS_MODULE_OPENCASCADE=ON \ -S ${{github.workspace}} \ -B ${{github.workspace}}/build @@ -209,7 +219,7 @@ jobs: simbody ` gtest ` xsimd ` - pybind11 + pybind11 - uses: ilammy/msvc-dev-cmd@v1 @@ -297,7 +307,7 @@ jobs: - name: Install dependencies run: | - ${{github.workspace}}/vcpkg/vcpkg install --clean-after-build \ + ${{github.workspace}}/vcpkg/vcpkg install --clean-after-build --allow-unsupported \ eigen3 \ tbb \ boost-program-options \ @@ -305,7 +315,8 @@ jobs: gtest \ simbody \ xsimd \ - pybind11 + pybind11 \ + opencascade - name: Generate buildsystem run: | @@ -356,4 +367,4 @@ jobs: if: ${{ steps.fourth-try.outcome == 'failure' }} run: | cd build - ctest --rerun-failed --output-on-failure \ No newline at end of file + ctest --rerun-failed --output-on-failure diff --git a/CMakeLists.txt b/CMakeLists.txt index dda171be74..397308311a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ option(SPHINXSYS_3D "Build sphinxsys_3d library" ON) option(SPHINXSYS_BUILD_TESTS "Build tests" ON) option(SPHINXSYS_DEVELOPER_MODE "Developer mode has more flags active for code quality" ON) option(SPHINXSYS_USE_FLOAT "Build using float (single-precision floating-point format) as primary type" OFF) +option(SPHINXSYS_MODULE_OPENCASCADE "Build extension relying on OpenCASCADE" OFF) # ------ Global properties (Some cannot be set on INTERFACE targets) set(CMAKE_VERBOSE_MAKEFILE OFF CACHE BOOL "Enable verbose compilation commands for Makefile and Ninja" FORCE) # Extra fluff needed for Ninja: https://github.com/ninja-build/ninja/issues/900 diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt old mode 100755 new mode 100644 index 6ea2286337..e1e9930061 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -1,3 +1,7 @@ -add_library(structural_simulation_module structural_simulation/structural_simulation_class.cpp structural_simulation/structural_simulation_class.h) -target_include_directories(structural_simulation_module PUBLIC $ $) -target_link_libraries(structural_simulation_module PUBLIC sphinxsys_3d) +SUBDIRLIST(SUBDIRS ${CMAKE_CURRENT_SOURCE_DIR}) + +foreach(subdir ${SUBDIRS}) + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/CMakeLists.txt) + add_subdirectory(${subdir}) + endif() +endforeach() diff --git a/modules/opencascade/CMakeLists.txt b/modules/opencascade/CMakeLists.txt new file mode 100644 index 0000000000..1c15bc43e5 --- /dev/null +++ b/modules/opencascade/CMakeLists.txt @@ -0,0 +1,29 @@ +if(NOT SPHINXSYS_MODULE_OPENCASCADE OR ${CMAKE_SYSTEM_NAME} MATCHES "Windows") + return() +endif() + +find_package(OpenCASCADE CONFIG REQUIRED) +# Must be shared library if OpenCASCADE is built static otherwise coplyeft OpenCASCADE license propagates +get_target_property(OCCT_LIBRARY_TYPE TKernel TYPE) # https://cmake.org/cmake/help/latest/prop_tgt/TYPE.html +if(OCCT_LIBRARY_TYPE MATCHES "STATIC_LIBRARY") + set(SPHINXSYS_OPENCASCADE_LIBRARY_TYPE SHARED) +endif() +add_library(sphinxsys_opencascade + ${SPHINXSYS_OPENCASCADE_LIBRARY_TYPE} + opencascade/relax_dynamics_surface.cpp + opencascade/relax_dynamics_surface.h + opencascade/surface_shape.cpp + opencascade/surface_shape.h + opencascade/vector.cpp + opencascade/vector.h +) +target_include_directories(sphinxsys_opencascade PUBLIC $) +target_link_libraries(sphinxsys_opencascade PUBLIC sphinxsys_3d) + +# Must list all dependent packages given here https://dev.opencascade.org/doc/refman/html/toolkit_tkstep.html because improper CMake target link visibility +target_link_libraries(sphinxsys_opencascade PRIVATE TKSTEP TKSTEPAttr TKSTEP209 TKSTEPBase TKXSBase TKShHealing TKTopAlgo TKGeomAlgo TKBRep TKGeomBase) +target_link_libraries(sphinxsys_opencascade PUBLIC TKG3d TKG2d TKMath TKernel) + +if(SPHINXSYS_BUILD_TESTS) + add_subdirectory(tests) +endif() \ No newline at end of file diff --git a/modules/opencascade/opencascade/relax_dynamics_surface.cpp b/modules/opencascade/opencascade/relax_dynamics_surface.cpp new file mode 100644 index 0000000000..daa373e287 --- /dev/null +++ b/modules/opencascade/opencascade/relax_dynamics_surface.cpp @@ -0,0 +1,106 @@ +#include "level_set_shape.h" +#include "surface_shape.h" +#include "relax_dynamics_surface.h" + +#include +#include + +//========================================================================================================// +namespace SPH +{ + //=====================================================================================================// + namespace relax_dynamics + { + //=================================================================================================// + ShapeSurfaceBounding2::ShapeSurfaceBounding2(RealBody &real_body_) + : LocalDynamics(real_body_), RelaxDataDelegateSimple(real_body_), pos_(particles_->pos_) + { + shape_ = real_body_.body_shape_; + + } + //=================================================================================================// + void ShapeSurfaceBounding2::update(size_t index_i, Real dt) + { + pos_[index_i] = shape_->findClosestPoint(pos_[index_i]); + + } + //=================================================================================================// + RelaxationStepInnerFirstHalf:: + RelaxationStepInnerFirstHalf(BaseInnerRelation &inner_relation, bool level_set_correction) + : BaseDynamics(inner_relation.getSPHBody()), real_body_(inner_relation.real_body_), + inner_relation_(inner_relation) + { + relaxation_acceleration_inner_ = + makeUnique>(inner_relation); + } + //=================================================================================================// + void RelaxationStepInnerFirstHalf::exec(Real dt) + { + real_body_->updateCellLinkedList(); + inner_relation_.updateConfiguration(); + relaxation_acceleration_inner_->exec(); + } + + //=================================================================================================// + RelaxationStepInnerSecondHalf:: + RelaxationStepInnerSecondHalf(BaseInnerRelation &inner_relation, bool level_set_correction) + : BaseDynamics(inner_relation.getSPHBody()), real_body_(inner_relation.real_body_), + get_time_step_square_(*real_body_), update_particle_position_(*real_body_), + surface_bounding_(*real_body_) + { + } + //=================================================================================================// + void RelaxationStepInnerSecondHalf::exec(Real dt) + { + Real dt_square = get_time_step_square_.exec(); + update_particle_position_.exec(dt_square); + surface_bounding_.exec(); + } + + //=================================================================================================// + SurfaceNormalDirection::SurfaceNormalDirection(SPHBody &sph_body) + : RelaxDataDelegateSimple(sph_body), LocalDynamics(sph_body), + surface_shape_(DynamicCast(this, sph_body.body_shape_)), + pos_(particles_->pos_), n_(*particles_->getVariableByName("NormalDirection")) {} + + //=================================================================================================// + void SurfaceNormalDirection::update(size_t index_i, Real dt) + { + Extrema_ExtAlgo Algo = Extrema_ExtAlgo_Tree; + gp_Vec tangent_u, tangent_v; + gp_Vec norm; + Vecd normal_direction_; + + + gp_Pnt point1 = EigenToOcct(pos_[index_i]); + GeomAPI_ProjectPointOnSurf pointonsurf(point1, surface_shape_->surface_, Algo); + + + Standard_Real u; + Standard_Real v; + gp_Pnt Point; + + pointonsurf.Parameters(1, u, v); + + surface_shape_->surface_->D1(u, v, Point, tangent_u, tangent_v); + norm = tangent_u.Crossed(tangent_v); + normal_direction_ = OcctVecToEigen(norm); + n_[index_i] = normal_direction_.normalized(); + } + //=================================================================================================// + ConstrainSurfaceBodyRegion:: + ConstrainSurfaceBodyRegion(BodyPartByParticle &body_part) + : BaseLocalDynamics(body_part), RelaxDataDelegateSimple(sph_body_), + acc_(particles_->acc_) + { + } + //=================================================================================================// + void ConstrainSurfaceBodyRegion::update(size_t index_i, Real dt) + { + acc_[index_i] = Vecd::Zero(); + } + //=================================================================================================// + } + //=================================================================================================// +} +//=================================================================================================// diff --git a/modules/opencascade/opencascade/relax_dynamics_surface.h b/modules/opencascade/opencascade/relax_dynamics_surface.h new file mode 100644 index 0000000000..35d4de8855 --- /dev/null +++ b/modules/opencascade/opencascade/relax_dynamics_surface.h @@ -0,0 +1,124 @@ +/* -------------------------------------------------------------------------* + * SPHinXsys * + * -------------------------------------------------------------------------* + * SPHinXsys (pronunciation: s'finksis) is an acronym from Smoothed Particle* + * Hydrodynamics for industrial compleX systems. It provides C++ APIs for * + * physical accurate simulation and aims to model coupled industrial dynamic* + * systems including fluid, solid, multi-body dynamics and beyond with SPH * + * (smoothed particle hydrodynamics), a meshless computational method using * + * particle discretization. * + * * + * SPHinXsys is partially funded by German Research Foundation * + * (Deutsche Forschungsgemeinschaft) DFG HU1527/6-1, HU1527/10-1, * + * HU1527/12-1 and HU1527/12-4 * + * * + * Portions copyright (c) 2017-2022 Technical University of Munich and * + * the authors' affiliations. * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); you may * + * not use this file except in compliance with the License. You may obtain a* + * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * + * * + * ------------------------------------------------------------------------*/ +/** + * @file relax_dynamics.h + * @brief This is the classes of particle relaxation in order to produce body fitted + * initial particle distribution. + * @author Chi Zhang and Xiangyu Hu + */ + +#ifndef RELAX_DYNAMICS_SURFACE_H +#define RELAX_DYNAMICS_SURFACE_H + +#include "sphinxsys.h" +#include "vector.h" +#include "surface_shape.h" + +namespace SPH +{ + + class SurfaceShape; + + namespace relax_dynamics + { + class ShapeSurfaceBounding2 : public LocalDynamics, + public RelaxDataDelegateSimple + { + public: + ShapeSurfaceBounding2(RealBody &real_body_); + virtual ~ShapeSurfaceBounding2(){}; + void update(size_t index_i, Real dt = 0.0); + + protected: + StdLargeVec &pos_; + Shape *shape_; + }; + + + class RelaxationStepInnerFirstHalf : public BaseDynamics + { + public: + explicit RelaxationStepInnerFirstHalf(BaseInnerRelation &inner_relation, + bool level_set_correction = false); + virtual ~RelaxationStepInnerFirstHalf(){}; + virtual void exec(Real dt = 0.0) override; + + + protected: + RealBody *real_body_; + BaseInnerRelation &inner_relation_; + UniquePtr> relaxation_acceleration_inner_; + }; + + class RelaxationStepInnerSecondHalf : public BaseDynamics + { + public: + explicit RelaxationStepInnerSecondHalf(BaseInnerRelation &inner_relation, + bool level_set_correction = false); + virtual ~RelaxationStepInnerSecondHalf(){}; + SimpleDynamics &SurfaceBounding() { return surface_bounding_; }; + virtual void exec(Real dt = 0.0) override; + + + protected: + RealBody *real_body_; + ReduceDynamics get_time_step_square_; + SimpleDynamics update_particle_position_; + SimpleDynamics surface_bounding_; + }; + + /** + * @class SurfaceNormalDirection + * @brief get the normal direction of surface particles. + */ + class SurfaceNormalDirection : public RelaxDataDelegateSimple, public LocalDynamics + { + public: + explicit SurfaceNormalDirection(SPHBody &sph_body); + virtual ~SurfaceNormalDirection(){}; + void update(size_t index_i, Real dt = 0.0); + + protected: + SurfaceShape *surface_shape_; + StdLargeVec &pos_, &n_; + }; + + + /**@class ConstrainSuefaceBodyRegion + * @brief Fix the position surafce body part. + */ + class ConstrainSurfaceBodyRegion : public BaseLocalDynamics, public RelaxDataDelegateSimple + { + public: + ConstrainSurfaceBodyRegion(BodyPartByParticle &body_part); + virtual ~ConstrainSurfaceBodyRegion(){}; + void update(size_t index_i, Real dt = 0.0); + + protected: + StdLargeVec &acc_; + }; + + + } + } +#endif // RELAX_DYNAMICS_H diff --git a/modules/opencascade/opencascade/surface_shape.cpp b/modules/opencascade/opencascade/surface_shape.cpp new file mode 100644 index 0000000000..fc889e163d --- /dev/null +++ b/modules/opencascade/opencascade/surface_shape.cpp @@ -0,0 +1,70 @@ +#include "surface_shape.h" + +#include +#include +#include +#include +#include +#include + +namespace SPH +{ + //=================================================================================================// +Vecd SurfaceShape::findClosestPoint(const Vecd &input_pnt) +{ + + Vecd closest_pnt; + gp_Pnt point1 = EigenToOcct(input_pnt); + Extrema_ExtAlgo Algo = Extrema_ExtAlgo_Tree; + gp_Pnt point2 = GeomAPI_ProjectPointOnSurf(point1, surface_, Algo); + closest_pnt[0] = point2.X(); + closest_pnt[1] = point2.Y(); + closest_pnt[2] = point2.Z(); + + return closest_pnt; +} + +////=================================================================================================// +bool SurfaceShape::checkContain(const Vecd &pnt, bool BOUNDARY_INCLUDED) { return 0; } +BoundingBox SurfaceShape::findBounds() { return BoundingBox(); } +//=================================================================================================// + +Vecd SurfaceShape::getCartesianPoint(Standard_Real u, Standard_Real v) +{ + gp_Pnt point; + Vec3d actual_pnt; + point = surface_->Value(u, v); + actual_pnt[0] = point.X(); + actual_pnt[1] = point.Y(); + actual_pnt[2] = point.Z(); + return Vecd(actual_pnt[0], actual_pnt[1], actual_pnt[2]); +} + +//=================================================================================================// +SurfaceShapeSTEP:: + SurfaceShapeSTEP(Standard_CString &filepathname, const std::string &shape_name) + : SurfaceShape(shape_name) +{ + if (!std::filesystem::exists(filepathname)) + { + std::cout << "\n Error: the input file:" << filepathname << " is not exists" << std::endl; + std::cout << __FILE__ << ':' << __LINE__ << std::endl; + throw; + } + STEPControl_Reader step_reader; + step_reader.ReadFile(filepathname); + + for (Standard_Integer i = 1; i <= step_reader.NbRootsForTransfer(); i++) + step_reader.TransferRoot(i); + + TopoDS_Shape step_shape; + for (Standard_Integer i = 1; i <= step_reader.NbShapes(); i++) + step_shape = step_reader.Shape(i); + + TopExp_Explorer explorer(step_shape, TopAbs_FACE); + TopoDS_Face face = TopoDS::Face(explorer.Current()); + surface_ = BRep_Tool::Surface(face); +} + + //=================================================================================================// +} diff --git a/modules/opencascade/opencascade/surface_shape.h b/modules/opencascade/opencascade/surface_shape.h new file mode 100644 index 0000000000..b257d69132 --- /dev/null +++ b/modules/opencascade/opencascade/surface_shape.h @@ -0,0 +1,57 @@ +/* -------------------------------------------------------------------------* + * SPHinXsys * + * -------------------------------------------------------------------------* + * SPHinXsys (pronunciation: s'finksis) is an acronym from Smoothed Particle* + * Hydrodynamics for industrial compleX systems. It provides C++ APIs for * + * physical accurate simulation and aims to model coupled industrial dynamic* + * systems including fluid, solid, multi-body dynamics and beyond with SPH * + * (smoothed particle hydrodynamics), a meshless computational method using * + * particle discretization. * * + * ------------------------------------------------------------------------*/ + + +#ifndef SURFACE_SHAPE_H +#define SURFACE_SHAPE_H + +#include "sphinxsys.h" +#include "vector.h" + +#include +#include + +#include +#include +#include +#include +namespace fs = std::filesystem; + +namespace SPH +{ + class SurfaceShape : public Shape + { + public: + explicit SurfaceShape(const std::string &shape_name) + : Shape(shape_name){}; + virtual bool checkContain(const Vecd &pnt, bool BOUNDARY_INCLUDED = true) override; + virtual Vecd findClosestPoint(const Vecd &input_pnt) override; + Vecd getCartesianPoint(Standard_Real u, Standard_Real v); + + Handle_Geom_Surface surface_; + protected: + virtual BoundingBox findBounds() override; + }; + + class SurfaceShapeSTEP : public SurfaceShape + { + + public: + // constructor for load STEP file from out side + explicit SurfaceShapeSTEP(Standard_CString &filepathname, + const std::string &shape_name = "SurfaceShapeSTEP"); + virtual ~SurfaceShapeSTEP(){}; + + }; + +} + +#endif //SURFACE_SHAPE_H diff --git a/modules/opencascade/opencascade/vector.cpp b/modules/opencascade/opencascade/vector.cpp new file mode 100644 index 0000000000..8ab344196e --- /dev/null +++ b/modules/opencascade/opencascade/vector.cpp @@ -0,0 +1,22 @@ +#include "vector.h" +//=================================================================================================// +namespace SPH +{ + //=================================================================================================// + Vec3d OcctToEigen(const gp_Pnt &occt_vector) + { + return Vec3d(occt_vector.X(), occt_vector.Y(), occt_vector.Z()); + } + //=================================================================================================// + gp_Pnt EigenToOcct(const Vec3d &eigen_vector) + { + return gp_Pnt(eigen_vector[0], eigen_vector[1], eigen_vector[2]); + } + //=================================================================================================// + Vec3d OcctVecToEigen(const gp_Vec &occt_vector) + { + return Vec3d(occt_vector.X(), occt_vector.Y(), occt_vector.Z()); + } + //=================================================================================================// + +} diff --git a/modules/opencascade/opencascade/vector.h b/modules/opencascade/opencascade/vector.h new file mode 100644 index 0000000000..9f83e253fc --- /dev/null +++ b/modules/opencascade/opencascade/vector.h @@ -0,0 +1,41 @@ +/* -------------------------------------------------------------------------* + * SPHinXsys * + * -------------------------------------------------------------------------* + * SPHinXsys (pronunciation: s'finksis) is an acronym from Smoothed Particle* + * Hydrodynamics for industrial compleX systems. It provides C++ APIs for * + * physical accurate simulation and aims to model coupled industrial dynamic* + * systems including fluid, solid, multi-body dynamics and beyond with SPH * + * (smoothed particle hydrodynamics), a meshless computational method using * + * particle discretization. * + * * + * SPHinXsys is partially funded by German Research Foundation * + * (Deutsche Forschungsgemeinschaft) DFG HU1527/6-1, HU1527/10-1, * + * HU1527/12-1 and HU1527/12-4 * + * * + * Portions copyright (c) 2017-2022 Technical University of Munich and * + * the authors' affiliations. * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); you may * + * not use this file except in compliance with the License. You may obtain a* + * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * + * * + * ------------------------------------------------------------------------*/ +/** + * @file vector_functions.h + * @brief Basic functions for vector type data. + * @author Chi ZHang and Xiangyu Hu + */ +#ifndef VECTOR_H +#define VECTOR_H + +#include "base_data_type.h" +#include + +namespace SPH +{ + Vec3d OcctToEigen(const gp_Pnt &occt_vector); + gp_Pnt EigenToOcct(const Vec3d &eigen_vector); + Vec3d OcctVecToEigen(const gp_Vec &occt_vector); + +} +#endif // SMALL_VECTORS_H diff --git a/modules/opencascade/tests/CMakeLists.txt b/modules/opencascade/tests/CMakeLists.txt new file mode 100644 index 0000000000..e1e9930061 --- /dev/null +++ b/modules/opencascade/tests/CMakeLists.txt @@ -0,0 +1,7 @@ +SUBDIRLIST(SUBDIRS ${CMAKE_CURRENT_SOURCE_DIR}) + +foreach(subdir ${SUBDIRS}) + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/CMakeLists.txt) + add_subdirectory(${subdir}) + endif() +endforeach() diff --git a/modules/opencascade/tests/test_3d_aortic_valve/CMakeLists.txt b/modules/opencascade/tests/test_3d_aortic_valve/CMakeLists.txt new file mode 100644 index 0000000000..0029e7ea26 --- /dev/null +++ b/modules/opencascade/tests/test_3d_aortic_valve/CMakeLists.txt @@ -0,0 +1,23 @@ +STRING(REGEX REPLACE ".*/(.*)" "\\1" CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}) +PROJECT("${CURRENT_FOLDER}") + +SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) +SET(EXECUTABLE_OUTPUT_PATH "${PROJECT_BINARY_DIR}/bin/") +SET(BUILD_INPUT_PATH "${EXECUTABLE_OUTPUT_PATH}/input") +SET(BUILD_RELOAD_PATH "${EXECUTABLE_OUTPUT_PATH}/reload") + +file(MAKE_DIRECTORY ${BUILD_INPUT_PATH}) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/ + DESTINATION ${BUILD_INPUT_PATH}) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/regression_test_tool/ + DESTINATION ${BUILD_INPUT_PATH}) + +add_executable(${PROJECT_NAME}) +aux_source_directory(. DIR_SRCS) +target_sources(${PROJECT_NAME} PRIVATE ${DIR_SRCS}) +target_link_libraries(${PROJECT_NAME} sphinxsys_opencascade) +set_target_properties(${PROJECT_NAME} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}") + +add_test(NAME ${PROJECT_NAME} + COMMAND ${PROJECT_NAME} + WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) \ No newline at end of file diff --git a/modules/opencascade/tests/test_3d_aortic_valve/aortic_valve.cpp b/modules/opencascade/tests/test_3d_aortic_valve/aortic_valve.cpp new file mode 100644 index 0000000000..369b72eafa --- /dev/null +++ b/modules/opencascade/tests/test_3d_aortic_valve/aortic_valve.cpp @@ -0,0 +1,182 @@ +/** + * @file test_3d_surface_particle_relaxation.cpp + * @brief This is the test of using OCCT to import surface model,and then generate particles with single resolution and relax particles. + * @details We use this case to test the particle generation and relaxation for a surface geometry (3D). + */ + +#include "sphinxsys.h" // SPHinXsys Library. +#include "relax_dynamics_surface.h" +#include "surface_shape.h" + + +using namespace SPH; +//---------------------------------------------------------------------- +// Set the file path to the data file. +//---------------------------------------------------------------------- +Standard_CString full_path_to_geometry = "./input/valve.STEP"; +//---------------------------------------------------------------------- +// Basic geometry parameters and numerical setup. +//---------------------------------------------------------------------- +Real thickness = 1; +Real PL = 13.95; +int particle_number = 10; /** Particle number in the peripheral direction. */ +Real particle_spacing_ref = PL / (Real)particle_number; +double DELTA1 = 0.1; +double DELTA2 = 0.05; + +Vec3d domain_lower_bound(-15.0, 0.0, 0.0); +Vec3d domain_upper_bound(15.0, 15.0, 26.0); +//---------------------------------------------------------------------- +// Domain bounds of the system. +//---------------------------------------------------------------------- +BoundingBox system_domain_bounds(domain_lower_bound, domain_upper_bound); +/** Define the boundary geometry. */ +class BoundaryGeometry : public BodyPartByParticle +{ + public: + BoundaryGeometry(SPHBody &body, const std::string &body_part_name) + : BodyPartByParticle(body, body_part_name) + { + TaggingParticleMethod tagging_particle_method = std::bind(&BoundaryGeometry::tagManually, this, _1); + tagParticles(tagging_particle_method); + }; + virtual ~BoundaryGeometry(){}; + + private: + void tagManually(size_t index_i) + { + if (index_i >= 0 && index_i <= (2 / DELTA1 + 2 / DELTA2 - 1)) + { + body_part_particles_.push_back(index_i); + } + }; +}; + +class CylinderParticleGenerator : public SurfaceParticleGenerator +{ + public: + explicit CylinderParticleGenerator(SPHBody &sph_body) : SurfaceParticleGenerator(sph_body), sph_body_(sph_body){}; + virtual void initializeGeometricVariables() override + { + SurfaceShape *a = dynamic_cast(sph_body_.body_shape_); + + Standard_Real u1 = 0; + Standard_Real v1 = DELTA1; + Standard_Real u2 = DELTA2; + Standard_Real v2 = DELTA2; + + std::vector points; + for (size_t k = 0; k <= 1 / DELTA1; k++) + { + Standard_Real u = u1 + k * DELTA1; + points.push_back(a->getCartesianPoint(u, 0)); + } + for (size_t k = 0; k <= 1 / DELTA1-1; k++) + { + Standard_Real v = v1 + k * DELTA1; + points.push_back(a->getCartesianPoint(0, v)); + } + + for (size_t n = 0; n <= 1 / DELTA2 - 2; n++) + { + Standard_Real u = u2 + n * DELTA2; + points.push_back(a->getCartesianPoint(u, 1)); + } + + for (size_t n = 0; n <= 1 / DELTA2 - 1; n++) + { + Standard_Real v = v2 + n * DELTA2; + points.push_back(a->getCartesianPoint(1, v)); + } + + for (size_t k = 0; k <= 8; k++) + { + v1 = 0.5; + u1 = 0.5; + double VDELTA = 0.005; + double UDELTA = 0.005; + Standard_Real v = v1 + k * VDELTA; + for (size_t n = 0; n <= 20; n++) + { + Standard_Real u = u1 + n * UDELTA; + points.push_back(a->getCartesianPoint(u, v)); + } + } + + for (int i = 0; i != (int)points.size(); i++) + { + initializePositionAndVolumetricMeasure(points[i], particle_spacing_ref * particle_spacing_ref); + Vecd n_0 = Vec3d(1.0, 1.0, 1.0); + initializeSurfaceProperties(n_0, thickness); + } + } + SPHBody &sph_body_; +}; + +//-------------------------------------------------------------------------- +// Main program starts here. +//-------------------------------------------------------------------------- +int main(int ac, char *av[]) +{ + //---------------------------------------------------------------------- + // Build up a SPHSystem. + //---------------------------------------------------------------------- + SPHSystem system(system_domain_bounds, particle_spacing_ref); + IOEnvironment io_environment(system); + //---------------------------------------------------------------------- + // Creating body, materials and particles. + //---------------------------------------------------------------------- + SolidBody leaflet(system, makeShared(full_path_to_geometry, "Leaflet")); + // here dummy linear elastic solid is use because no solid dynamics in particle relaxation + leaflet.defineParticlesAndMaterial(1.0, 1.0, 0.0); + leaflet.generateParticles(); + //---------------------------------------------------------------------- + // Define simple file input and outputs functions. + //---------------------------------------------------------------------- + BodyStatesRecordingToVtp write_relaxed_particles(io_environment, system.real_bodies_); + MeshRecordingToPlt write_mesh_cell_linked_list(io_environment, leaflet.getCellLinkedList()); + //---------------------------------------------------------------------- + // Define body relation map. + // The contact map gives the topological connections between the bodies. + // Basically the the range of bodies to build neighbor particle lists. + //---------------------------------------------------------------------- + InnerRelation leaflet_inner(leaflet); + //---------------------------------------------------------------------- + // Methods used for particle relaxation. + //---------------------------------------------------------------------- + /** A Physics relaxation step. */ + relax_dynamics::RelaxationStepInnerFirstHalf leaflet_relaxation_first_half(leaflet_inner); + relax_dynamics::RelaxationStepInnerSecondHalf leaflet_relaxation_second_half(leaflet_inner); + /** Constrain the boundary. */ + BoundaryGeometry boundary_geometry(leaflet, "BoundaryGeometry"); + SimpleDynamics constrain_holder(boundary_geometry); + SimpleDynamics surface_normal_direction(leaflet); + //---------------------------------------------------------------------- + // Particle relaxation starts here. + //---------------------------------------------------------------------- + write_relaxed_particles.writeToFile(0); + leaflet.updateCellLinkedList(); + write_mesh_cell_linked_list.writeToFile(0.0); + //---------------------------------------------------------------------- + // Particle relaxation time stepping start here. + //---------------------------------------------------------------------- + int ite = 0; + int relax_step = 1000; + while (ite < relax_step) + { + leaflet_relaxation_first_half.exec(); + constrain_holder.exec(); + leaflet_relaxation_second_half.exec(); + ite += 1; + if (ite % 100 == 0) + { + std::cout << std::fixed << std::setprecision(9) << "Relaxation steps N = " << ite << "\n"; + write_relaxed_particles.writeToFile(ite); + } + } + surface_normal_direction.exec(); + write_relaxed_particles.writeToFile(ite); + std::cout << "The physics relaxation process of surface particles finish !" << std::endl; + + return 0; +} diff --git a/modules/opencascade/tests/test_3d_aortic_valve/data/valve.STEP b/modules/opencascade/tests/test_3d_aortic_valve/data/valve.STEP new file mode 100644 index 0000000000..d1c5efc616 --- /dev/null +++ b/modules/opencascade/tests/test_3d_aortic_valve/data/valve.STEP @@ -0,0 +1,222 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION (( 'STEP AP203' ), + '1' ); +FILE_NAME ('10.STEP', + '2023-03-04T08:36:53', + ( '' ), + ( '' ), + 'SwSTEP 2.0', + 'SolidWorks 2019', + '' ); +FILE_SCHEMA (( 'CONFIG_CONTROL_DESIGN' )); +ENDSEC; + +DATA; +#1 = CC_DESIGN_APPROVAL ( #162, ( #58 ) ) ; +#2 = EDGE_LOOP ( 'NONE', ( #40, #88, #28, #117 ) ) ; +#3 = CARTESIAN_POINT ( 'NONE', ( -9.766652592117676335, 6.414667323984693859, 4.012541891772535507 ) ) ; +#4 = OPEN_SHELL ( 'NONE', ( #113 ) ) ; +#5 = CARTESIAN_POINT ( 'NONE', ( 11.44020042968491246, 7.379346065850916681, 4.302613453000696531 ) ) ; +#6 = CC_DESIGN_DATE_AND_TIME_ASSIGNMENT ( #103, #51, ( #58 ) ) ; +#7 = CARTESIAN_POINT ( 'NONE', ( 7.397985761319059161E-15, 14.73300000000000232, 25.28219999999999601 ) ) ; +#8 = CARTESIAN_POINT ( 'NONE', ( 0.03771071596828774741, 2.351541853555801254, 2.032106652836086269 ) ) ; +#9 = LOCAL_TIME ( 16, 36, 53.00000000000000000, #129 ) ; +#10 = CALENDAR_DATE ( 2023, 4, 3 ) ; +#11 = PRODUCT_DEFINITION_SHAPE ( 'NONE', 'NONE', #58 ) ; +#12 = CARTESIAN_POINT ( 'NONE', ( 0.03771071596828774741, 2.351541853555801254, 2.032106652836086269 ) ) ; +#13 = APPROVAL_STATUS ( 'not_yet_approved' ) ; +#14 = B_SPLINE_CURVE_WITH_KNOTS ( 'NONE', 3, + ( #93, #61, #124, #20, #137, #73 ), + .UNSPECIFIED., .F., .F., + ( 4, 1, 1, 4 ), + ( 0.000000000000000000, 0.5831580577263300036, 0.7536333900141753972, 1.000000000000000000 ), + .UNSPECIFIED. ) ; +#15 = APPROVAL_PERSON_ORGANIZATION ( #33, #126, #26 ) ; +#16 = CARTESIAN_POINT ( 'NONE', ( 11.44020042968491246, 7.379346065850916681, 4.302613453000696531 ) ) ; +#17 = CARTESIAN_POINT ( 'NONE', ( 2.342009656156821773, 14.72759591755670705, 25.26743993509780495 ) ) ; +#18 = CARTESIAN_POINT ( 'NONE', ( -5.795029609302901896, 4.056064149584640788, 3.108632770463582329 ) ) ; +#19 = CARTESIAN_POINT ( 'NONE', ( 3.306674013599882223, 13.62326625680870862, 22.90140639743690798 ) ) ; +#20 = CARTESIAN_POINT ( 'NONE', ( 5.602418292964242319, 13.82287451810998036, 23.17404837305776866 ) ) ; +#21 = EDGE_CURVE ( 'NONE', #81, #90, #104, .T. ) ; +#22 = LOCAL_TIME ( 16, 36, 53.00000000000000000, #116 ) ; +#23 = DIRECTION ( 'NONE', ( 0.000000000000000000, 0.000000000000000000, 1.000000000000000000 ) ) ; +#24 = DATE_TIME_ROLE ( 'classification_date' ) ; +#25 = EDGE_CURVE ( 'NONE', #172, #37, #52, .T. ) ; +#26 = APPROVAL_ROLE ( '' ) ; +#27 = PERSON_AND_ORGANIZATION ( #111, #39 ) ; +#28 = ORIENTED_EDGE ( 'NONE', *, *, #25, .F. ) ; +#29 = CARTESIAN_POINT ( 'NONE', ( 7.397985761319059161E-15, 14.73300000000000232, 25.28219999999999601 ) ) ; +#30 = CARTESIAN_POINT ( 'NONE', ( 8.553397964845782298, 10.59766884188598013, 15.81464466110617195 ) ) ; +#31 = CARTESIAN_POINT ( 'NONE', ( -10.50586606657035915, 10.94880641329396553, 16.09708288149759881 ) ) ; +#32 = CARTESIAN_POINT ( 'NONE', ( -11.43473826156925988, 7.377327452023437537, 4.302837484582290095 ) ) ; +#33 = PERSON_AND_ORGANIZATION ( #111, #39 ) ; +#34 = DESIGN_CONTEXT ( 'detailed design', #140, 'design' ) ; +#35 = COORDINATED_UNIVERSAL_TIME_OFFSET ( 8, 0, .AHEAD. ) ; +#36 = PERSON_AND_ORGANIZATION_ROLE ( 'classification_officer' ) ; +#37 = VERTEX_POINT ( 'NONE', #128 ) ; +#38 = APPROVAL_ROLE ( '' ) ; +#39 = ORGANIZATION ( 'UNSPECIFIED', 'UNSPECIFIED', '' ) ; +#40 = ORIENTED_EDGE ( 'NONE', *, *, #21, .T. ) ; +#41 = APPROVAL_PERSON_ORGANIZATION ( #166, #162, #168 ) ; +#42 = CARTESIAN_POINT ( 'NONE', ( 0.01812775165966759930, 2.993828108489582362, 3.865165261731865698 ) ) ; +#43 = B_SPLINE_CURVE_WITH_KNOTS ( 'NONE', 3, + ( #45, #83, #18, #3, #70, #108 ), + .UNSPECIFIED., .F., .F., + ( 4, 1, 1, 4 ), + ( 0.000000000000000000, 0.5831580577263300036, 0.7536333900141753972, 1.000000000000000000 ), + .UNSPECIFIED. ) ; +#44 = CARTESIAN_POINT ( 'NONE', ( -10.40174484862748194, 8.237255692199004997, 9.394598133022649122 ) ) ; +#45 = CARTESIAN_POINT ( 'NONE', ( 0.03771071596828774741, 2.351541853555801254, 2.032106652836086269 ) ) ; +#46 = CARTESIAN_POINT ( 'NONE', ( 10.40544384960389479, 8.236595679328745589, 9.392953758042162704 ) ) ; +#47 = COORDINATED_UNIVERSAL_TIME_OFFSET ( 8, 0, .AHEAD. ) ; +#48 = MECHANICAL_CONTEXT ( 'NONE', #161, 'mechanical' ) ; +#49 =( GEOMETRIC_REPRESENTATION_CONTEXT ( 3 ) GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT ( ( #96 ) ) GLOBAL_UNIT_ASSIGNED_CONTEXT ( ( #134, #122, #57 ) ) REPRESENTATION_CONTEXT ( 'NONE', 'WORKASPACE' ) ); +#50 = PRODUCT ( '10', '10', '', ( #48 ) ) ; +#51 = DATE_TIME_ROLE ( 'creation_date' ) ; +#52 = B_SPLINE_CURVE_WITH_KNOTS ( 'NONE', 3, + ( #119, #55, #106, #114, #158, #29 ), + .UNSPECIFIED., .F., .F., + ( 4, 1, 1, 4 ), + ( 0.000000000000000000, 0.5831580577263300036, 0.7536333900141746200, 1.000000000000000000 ), + .UNSPECIFIED. ) ; +#53 = APPROVAL_STATUS ( 'not_yet_approved' ) ; +#54 = CARTESIAN_POINT ( 'NONE', ( 5.829214543124403569, 4.079192963827527052, 3.120993139534906202 ) ) ; +#55 = CARTESIAN_POINT ( 'NONE', ( -11.89442228484815445, 8.658035374981711385, 9.567122753155663517 ) ) ; +#56 = CARTESIAN_POINT ( 'NONE', ( -5.621066445640325426, 9.554929998161412641, 14.38666932589030267 ) ) ; +#57 =( NAMED_UNIT ( * ) SI_UNIT ( $, .STERADIAN. ) SOLID_ANGLE_UNIT ( ) ); +#58 = PRODUCT_DEFINITION ( 'UNKNOWN', '', #169, #34 ) ; +#59 = CARTESIAN_POINT ( 'NONE', ( -8.083336659164965354, 7.252103753564985489, 8.592056854410753175 ) ) ; +#60 = CC_DESIGN_DATE_AND_TIME_ASSIGNMENT ( #154, #24, ( #69 ) ) ; +#61 = CARTESIAN_POINT ( 'NONE', ( 11.89442228484815267, 8.658035374981730925, 9.567122753155635095 ) ) ; +#62 = SHAPE_DEFINITION_REPRESENTATION ( #11, #149 ) ; +#63 = APPROVAL_STATUS ( 'not_yet_approved' ) ; +#64 = LOCAL_TIME ( 16, 36, 53.00000000000000000, #47 ) ; +#65 = CARTESIAN_POINT ( 'NONE', ( 12.44670000000000876, 7.882969999999992261, 4.416159999999999641 ) ) ; +#66 = CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT ( #27, #36, ( #69 ) ) ; +#67 = CARTESIAN_POINT ( 'NONE', ( -2.702463135869067390, 2.575132166275888146, 2.326245572081405921 ) ) ; +#68 = CARTESIAN_POINT ( 'NONE', ( -12.44669999999999810, 7.882969999999995814, 4.416160000000000529 ) ) ; +#69 = SECURITY_CLASSIFICATION ( '', '', #78 ) ; +#70 = CARTESIAN_POINT ( 'NONE', ( -11.43473826156925988, 7.377327452023437537, 4.302837484582290095 ) ) ; +#71 = CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT ( #86, #173, ( #169 ) ) ; +#72 = CC_DESIGN_APPROVAL ( #126, ( #169 ) ) ; +#73 = CARTESIAN_POINT ( 'NONE', ( 7.397985761319059161E-15, 14.73300000000000232, 25.28219999999999601 ) ) ; +#74 = CARTESIAN_POINT ( 'NONE', ( -5.795029609302901896, 4.056064149584640788, 3.108632770463582329 ) ) ; +#75 = DATE_AND_TIME ( #130, #22 ) ; +#76 = PERSON_AND_ORGANIZATION ( #111, #39 ) ; +#77 = COORDINATED_UNIVERSAL_TIME_OFFSET ( 8, 0, .AHEAD. ) ; +#78 = SECURITY_CLASSIFICATION_LEVEL ( 'unclassified' ) ; +#79 = LOCAL_TIME ( 16, 36, 53.00000000000000000, #77 ) ; +#80 = CALENDAR_DATE ( 2023, 4, 3 ) ; +#81 = VERTEX_POINT ( 'NONE', #12 ) ; +#82 = CARTESIAN_POINT ( 'NONE', ( -2.342009656156806230, 14.72759591755669462, 25.26743993509780140 ) ) ; +#83 = CARTESIAN_POINT ( 'NONE', ( -2.702463135869067390, 2.575132166275888146, 2.326245572081405921 ) ) ; +#84 = CARTESIAN_POINT ( 'NONE', ( 12.44670000000000876, 7.882969999999992261, 4.416159999999999641 ) ) ; +#85 = CARTESIAN_POINT ( 'NONE', ( -3.215105332381231307, 4.704776550034665661, 6.083036518846287599 ) ) ; +#86 = PERSON_AND_ORGANIZATION ( #111, #39 ) ; +#87 = PERSON_AND_ORGANIZATION_ROLE ( 'creator' ) ; +#88 = ORIENTED_EDGE ( 'NONE', *, *, #94, .T. ) ; +#89 = SHELL_BASED_SURFACE_MODEL ( 'NONE', ( #4 ) ); +#90 = VERTEX_POINT ( 'NONE', #170 ) ; +#91 = CARTESIAN_POINT ( 'NONE', ( 0.001190673383578828371, 12.58310795513185099, 20.85789489266707974 ) ) ; +#92 = CARTESIAN_POINT ( 'NONE', ( 8.092726170293545351, 7.252703213690497641, 8.590194275229954712 ) ) ; +#93 = CARTESIAN_POINT ( 'NONE', ( 12.44670000000000876, 7.882969999999992261, 4.416159999999999641 ) ) ; +#94 = EDGE_CURVE ( 'NONE', #90, #37, #14, .T. ) ; +#95 = CARTESIAN_POINT ( 'NONE', ( 0.0001856907477696439677, 14.62123648109167107, 25.08403376275296282 ) ) ; +#96 = UNCERTAINTY_MEASURE_WITH_UNIT (LENGTH_MEASURE( 1.000000000000000082E-05 ), #134, 'distance_accuracy_value', 'NONE'); +#97 = APPROVAL_DATE_TIME ( #167, #162 ) ; +#98 = CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT ( #151, #87, ( #58 ) ) ; +#99 = DATE_AND_TIME ( #138, #9 ) ; +#100 = CC_DESIGN_SECURITY_CLASSIFICATION ( #69, ( #169 ) ) ; +#101 = DIRECTION ( 'NONE', ( 1.000000000000000000, 0.000000000000000000, 0.000000000000000000 ) ) ; +#102 = CARTESIAN_POINT ( 'NONE', ( 0.03771071596828774741, 2.351541853555801254, 2.032106652836086269 ) ) ; +#103 = DATE_AND_TIME ( #139, #143 ) ; +#104 = B_SPLINE_CURVE_WITH_KNOTS ( 'NONE', 3, + ( #102, #155, #54, #132, #16, #65 ), + .UNSPECIFIED., .F., .F., + ( 4, 1, 1, 4 ), + ( 0.000000000000000000, 0.5831580577263300036, 0.7536333900141746200, 1.000000000000000000 ), + .UNSPECIFIED. ) ; +#105 = APPROVAL_PERSON_ORGANIZATION ( #171, #163, #38 ) ; +#106 = CARTESIAN_POINT ( 'NONE', ( -10.50586606657035915, 10.94880641329396553, 16.09708288149759881 ) ) ; +#107 = CARTESIAN_POINT ( 'NONE', ( 5.626995461764204620, 9.554046331725224661, 14.38514507054248703 ) ) ; +#108 = CARTESIAN_POINT ( 'NONE', ( -12.44669999999999810, 7.882969999999995814, 4.416160000000000529 ) ) ; +#109 = CARTESIAN_POINT ( 'NONE', ( -8.551058052219026706, 10.59864027805577180, 15.81588529479189376 ) ) ; +#110 = CARTESIAN_POINT ( 'NONE', ( -9.766652592117676335, 6.414667323984693859, 4.012541891772535507 ) ) ; +#111 = PERSON ( 'UNSPECIFIED', 'UNSPECIFIED', 'UNSPECIFIED', ('UNSPECIFIED'), ('UNSPECIFIED'), ('UNSPECIFIED') ) ; +#112 = CARTESIAN_POINT ( 'NONE', ( 0.000000000000000000, 0.000000000000000000, 0.000000000000000000 ) ) ; +#113 = ADVANCED_FACE ( 'NONE', ( #159 ), #152, .T. ) ; +#114 = CARTESIAN_POINT ( 'NONE', ( -5.602418292964242319, 13.82287451810995016, 23.17404837305779708 ) ) ; +#115 = APPLICATION_PROTOCOL_DEFINITION ( 'international standard', 'config_control_design', 1994, #140 ) ; +#116 = COORDINATED_UNIVERSAL_TIME_OFFSET ( 8, 0, .AHEAD. ) ; +#117 = ORIENTED_EDGE ( 'NONE', *, *, #144, .F. ) ; +#118 = CC_DESIGN_APPROVAL ( #163, ( #69 ) ) ; +#119 = CARTESIAN_POINT ( 'NONE', ( -12.44669999999999810, 7.882969999999995814, 4.416160000000000529 ) ) ; +#120 = CARTESIAN_POINT ( 'NONE', ( 0.007366011053427826832, 6.725717977246441492, 9.975745165009071158 ) ) ; +#121 = CARTESIAN_POINT ( 'NONE', ( 5.829214543124403569, 4.079192963827527052, 3.120993139534906202 ) ) ; +#122 =( NAMED_UNIT ( * ) PLANE_ANGLE_UNIT ( ) SI_UNIT ( $, .RADIAN. ) ); +#123 = CARTESIAN_POINT ( 'NONE', ( -11.89442228484815445, 8.658035374981711385, 9.567122753155663517 ) ) ; +#124 = CARTESIAN_POINT ( 'NONE', ( 10.50586606657038580, 10.94880641329391935, 16.09708288149764144 ) ) ; +#125 = PERSON_AND_ORGANIZATION ( #111, #39 ) ; +#126 = APPROVAL ( #63, 'UNSPECIFIED' ) ; +#127 = APPROVAL_DATE_TIME ( #75, #163 ) ; +#128 = CARTESIAN_POINT ( 'NONE', ( 7.397985761319059161E-15, 14.73300000000000232, 25.28219999999999601 ) ) ; +#129 = COORDINATED_UNIVERSAL_TIME_OFFSET ( 8, 0, .AHEAD. ) ; +#130 = CALENDAR_DATE ( 2023, 4, 3 ) ; +#131 = CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT ( #125, #142, ( #50 ) ) ; +#132 = CARTESIAN_POINT ( 'NONE', ( 9.780547906578231476, 6.422798886822127962, 4.014987864088338299 ) ) ; +#133 = CARTESIAN_POINT ( 'NONE', ( 5.602418292964242319, 13.82287451810998036, 23.17404837305776866 ) ) ; +#134 =( LENGTH_UNIT ( ) NAMED_UNIT ( * ) SI_UNIT ( .MILLI., .METRE. ) ); +#135 = CARTESIAN_POINT ( 'NONE', ( 11.89442228484815267, 8.658035374981730925, 9.567122753155635095 ) ) ; +#136 = CARTESIAN_POINT ( 'NONE', ( -3.305733441715410503, 13.62353066781159860, 22.90167953143206603 ) ) ; +#137 = CARTESIAN_POINT ( 'NONE', ( 2.342009656156821773, 14.72759591755670705, 25.26743993509780495 ) ) ; +#138 = CALENDAR_DATE ( 2023, 4, 3 ) ; +#139 = CALENDAR_DATE ( 2023, 4, 3 ) ; +#140 = APPLICATION_CONTEXT ( 'configuration controlled 3d designs of mechanical parts and assemblies' ) ; +#141 = APPROVAL_DATE_TIME ( #99, #126 ) ; +#142 = PERSON_AND_ORGANIZATION_ROLE ( 'design_owner' ) ; +#143 = LOCAL_TIME ( 16, 36, 53.00000000000000000, #35 ) ; +#144 = EDGE_CURVE ( 'NONE', #81, #172, #43, .T. ) ; +#145 = CARTESIAN_POINT ( 'NONE', ( 9.780547906578231476, 6.422798886822127962, 4.014987864088338299 ) ) ; +#146 = APPLICATION_PROTOCOL_DEFINITION ( 'international standard', 'config_control_design', 1994, #161 ) ; +#147 = CARTESIAN_POINT ( 'NONE', ( -5.602418292964242319, 13.82287451810995016, 23.17404837305779708 ) ) ; +#148 = PRODUCT_RELATED_PRODUCT_CATEGORY ( 'detail', '', ( #50 ) ) ; +#149 = MANIFOLD_SURFACE_SHAPE_REPRESENTATION ( '10', ( #89, #157 ), #49 ) ; +#150 = CARTESIAN_POINT ( 'NONE', ( -12.44669999999999810, 7.882969999999995814, 4.416160000000000529 ) ) ; +#151 = PERSON_AND_ORGANIZATION ( #111, #39 ) ; +#152 = B_SPLINE_SURFACE_WITH_KNOTS ( 'NONE', 3, 3, ( + ( #8, #67, #74, #110, #32, #150 ), + ( #165, #42, #85, #59, #44, #123 ), + ( #121, #160, #120, #56, #109, #31 ), + ( #145, #92, #107, #91, #136, #147 ), + ( #5, #46, #30, #19, #95, #82 ), + ( #84, #135, #164, #133, #17, #7 ) ), + .UNSPECIFIED., .F., .F., .F., + ( 4, 1, 1, 4 ), + ( 4, 1, 1, 4 ), + ( 0.000000000000000000, 0.5831580577263300036, 0.7536333900141746200, 1.000000000000000000 ), + ( 0.000000000000000000, 0.5831580577263300036, 0.7536333900141753972, 1.000000000000000000 ), + .UNSPECIFIED. ) ; +#153 = PERSON_AND_ORGANIZATION_ROLE ( 'creator' ) ; +#154 = DATE_AND_TIME ( #80, #79 ) ; +#155 = CARTESIAN_POINT ( 'NONE', ( 2.755168524632421345, 2.600006375572188944, 2.342499031254716257 ) ) ; +#156 = CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT ( #76, #153, ( #169 ) ) ; +#157 = AXIS2_PLACEMENT_3D ( 'NONE', #112, #23, #101 ) ; +#158 = CARTESIAN_POINT ( 'NONE', ( -2.342009656156806230, 14.72759591755669462, 25.26743993509780140 ) ) ; +#159 = FACE_OUTER_BOUND ( 'NONE', #2, .T. ) ; +#160 = CARTESIAN_POINT ( 'NONE', ( 3.238331704466880456, 4.709184719348012749, 6.083752903065222206 ) ) ; +#161 = APPLICATION_CONTEXT ( 'configuration controlled 3d designs of mechanical parts and assemblies' ) ; +#162 = APPROVAL ( #53, 'UNSPECIFIED' ) ; +#163 = APPROVAL ( #13, 'UNSPECIFIED' ) ; +#164 = CARTESIAN_POINT ( 'NONE', ( 10.50586606657038580, 10.94880641329391935, 16.09708288149764144 ) ) ; +#165 = CARTESIAN_POINT ( 'NONE', ( 2.755168524632421345, 2.600006375572188944, 2.342499031254716257 ) ) ; +#166 = PERSON_AND_ORGANIZATION ( #111, #39 ) ; +#167 = DATE_AND_TIME ( #10, #64 ) ; +#168 = APPROVAL_ROLE ( '' ) ; +#169 = PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE ( 'ANY', '', #50, .NOT_KNOWN. ) ; +#170 = CARTESIAN_POINT ( 'NONE', ( 12.44670000000000876, 7.882969999999992261, 4.416159999999999641 ) ) ; +#171 = PERSON_AND_ORGANIZATION ( #111, #39 ) ; +#172 = VERTEX_POINT ( 'NONE', #68 ) ; +#173 = PERSON_AND_ORGANIZATION_ROLE ( 'design_supplier' ) ; +ENDSEC; +END-ISO-10303-21; diff --git a/modules/opencascade/tests/test_3d_aortic_valve/regression_test_tool/regression_test_tool.py b/modules/opencascade/tests/test_3d_aortic_valve/regression_test_tool/regression_test_tool.py new file mode 100644 index 0000000000..987924ce96 --- /dev/null +++ b/modules/opencascade/tests/test_3d_aortic_valve/regression_test_tool/regression_test_tool.py @@ -0,0 +1,44 @@ +# !/usr/bin/env python3 +import os +import sys + +path = os.path.abspath('../../../../../PythonScriptStore/RegressionTest') +sys.path.append(path) +from regression_test_base_tool import SphinxsysRegressionTest + +""" +case name: test_2d_stfb +""" + +case_name = "test_3d_stfb" +body_name = "FreeSurfaceGauge" +parameter_name = "FreeSurfaceHeight" +body_name_1 = "Observer" +parameter_name_1 = "Position" + +number_of_run_times = 0 +converged = 0 +sphinxsys = SphinxsysRegressionTest(case_name, body_name, parameter_name) +sphinxsys_1 = SphinxsysRegressionTest(case_name, body_name_1, parameter_name_1) + + +while True: + print("Now start a new run......") + sphinxsys.run_case() + number_of_run_times += 1 + converged = sphinxsys.read_dat_file() + converged_1 = sphinxsys_1.read_dat_file() + print("Please note: This is the", number_of_run_times, "run!") + if number_of_run_times <= 20: + if (converged == "true") and (converged_1 == "true"): + print("The tested parameters of all variables are converged, and the run will stop here!") + break + elif converged != "true": + print("The tested parameters of", sphinxsys.sphinxsys_parameter_name, "are not converged!") + continue + elif converged_1 != "true": + print("The tested parameters of", sphinxsys_1.sphinxsys_parameter_name, "are not converged!") + continue + else: + print("It's too many runs but still not converged, please try again!") + break diff --git a/modules/structural_simulation/CMakeLists.txt b/modules/structural_simulation/CMakeLists.txt new file mode 100755 index 0000000000..70ee5e3262 --- /dev/null +++ b/modules/structural_simulation/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(structural_simulation_module structural_simulation_class.cpp structural_simulation_class.h) +target_include_directories(structural_simulation_module PUBLIC $) +target_link_libraries(structural_simulation_module PUBLIC sphinxsys_3d)