From e2460595bf1c99c3e03bb0763abeca063210d2de Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 28 Sep 2023 08:36:26 +0200 Subject: [PATCH 01/60] [all] Replace ScopedAdvancedTimers by macros (#4203) * Replace all ScopedAdvancedTimer timers by macro * use SCOPED_TIMER_VARNAME for timers with a variable name --- .../animationloop/ConstraintAnimationLoop.cpp | 18 ++++----- .../animationloop/FreeMotionAnimationLoop.cpp | 4 +- .../animationloop/MultiStepAnimationLoop.cpp | 6 +-- .../animationloop/MultiTagAnimationLoop.cpp | 6 +-- .../detection/algorithm/CollisionPipeline.cpp | 4 +- .../algorithm/DirectSAPNarrowPhase.cpp | 10 ++--- .../collision/detection/algorithm/IncrSAP.cpp | 2 +- .../solver/GenericConstraintSolver.cpp | 18 ++++----- .../lagrangian/solver/LCPConstraintSolver.cpp | 36 +++++++++--------- .../TetrahedronDiffusionFEMForceField.inl | 6 +-- .../direct/AsyncSparseLDLSolver.inl | 4 +- .../direct/EigenDirectSparseSolver.inl | 6 +-- .../linearsolver/direct/SVDLinearSolver.inl | 8 ++-- .../direct/SparseCholeskySolver.inl | 4 +- .../linearsolver/direct/SparseLDLSolver.inl | 2 +- .../linearsolver/direct/SparseLDLSolverImpl.h | 4 +- .../linearsolver/direct/SparseLUSolver.inl | 4 +- .../linearsolver/iterative/CGLinearSolver.inl | 2 +- .../iterative/ShewchukPCGLinearSolver.inl | 10 ++--- .../linearsystem/MatrixLinearSystem.inl | 16 ++++---- .../linearsystem/TypedMatrixLinearSystem.inl | 4 +- .../backward/EulerImplicitSolver.cpp | 10 ++--- .../odesolver/backward/StaticSolver.cpp | 2 +- .../backward/VariationalSymplecticSolver.cpp | 12 +++--- .../odesolver/forward/EulerSolver.cpp | 18 ++++----- .../StandardTetrahedralFEMForceField.inl | 4 +- .../PolynomialRestShapeSpringsForceField.inl | 2 +- .../spring/PolynomialSpringsForceField.inl | 2 +- .../TetrahedralTensorMassForceField.inl | 6 +-- .../dynamic/EdgeSetTopologyModifier.cpp | 26 ++++++------- .../dynamic/PointSetTopologyModifier.cpp | 38 +++++++++---------- .../TetrahedronSetTopologyModifier.cpp | 6 +-- .../dynamic/TriangleSetTopologyModifier.cpp | 10 ++--- .../mapping/Hexa2QuadTopologicalMapping.cpp | 2 +- .../Quad2TriangleTopologicalMapping.cpp | 2 +- .../Tetra2TriangleTopologicalMapping.cpp | 2 +- .../Triangle2EdgeTopologicalMapping.cpp | 2 +- .../utility/TopologyBoundingTrasher.inl | 2 +- .../sofa/component/visual/VisualModelImpl.cpp | 10 ++--- .../Common/src/sofa/gui/common/BaseGUI.cpp | 2 +- Sofa/GUI/Qt/src/sofa/gui/qt/RealGUI.cpp | 2 +- .../simulation/CollisionAnimationLoop.cpp | 6 +-- .../sofa/simulation/DefaultAnimationLoop.cpp | 32 ++++++++-------- .../Core/src/sofa/simulation/PipelineImpl.cpp | 4 +- .../Core/src/sofa/simulation/Simulation.cpp | 10 ++--- .../Core/src/sofa/simulation/SolveVisitor.cpp | 2 +- .../DefaultCollisionGroupManager.cpp | 2 +- .../CudaStandardTetrahedralFEMForceField.inl | 4 +- .../CudaTetrahedralTensorMassForceField.inl | 4 +- .../src/SofaCarving/CarvingManager.cpp | 2 +- 50 files changed, 200 insertions(+), 200 deletions(-) diff --git a/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/ConstraintAnimationLoop.cpp b/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/ConstraintAnimationLoop.cpp index 9263a1bbb52c..09996aff42f2 100644 --- a/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/ConstraintAnimationLoop.cpp +++ b/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/ConstraintAnimationLoop.cpp @@ -336,7 +336,7 @@ void ConstraintAnimationLoop::launchCollisionDetection(const core::ExecParams* p ////////////////// COLLISION DETECTION/////////////////////////////////////////////////////////////////////////////////////////// { - helper::ScopedAdvancedTimer timer("Collision"); + SCOPED_TIMER("Collision"); computeCollision(params); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -357,7 +357,7 @@ void ConstraintAnimationLoop::freeMotion(const core::ExecParams* params, simulat ///////////////////////////////////////////// FREE MOTION ///////////////////////////////////////////////////////////// { - helper::ScopedAdvancedTimer freeMotionTimer("Free Motion"); + SCOPED_TIMER_VARNAME(freeMotionTimer, "Free Motion"); MechanicalBeginIntegrationVisitor(params, dt).execute(context); @@ -416,7 +416,7 @@ void ConstraintAnimationLoop::setConstraintEquations(const core::ExecParams* par msg_info_when(EMIT_EXTRA_DEBUG_MESSAGE) <<"constraints Matrix construction is called" ; { - helper::ScopedAdvancedTimer constraintDefinitionTimer("Constraints definition"); + SCOPED_TIMER_VARNAME(constraintDefinitionTimer, "Constraints definition"); if(!d_schemeCorrection.getValue()) { @@ -495,7 +495,7 @@ void ConstraintAnimationLoop::computeComplianceInConstraintSpace() /// calling getCompliance => getDelassusOperator(_W) = H*C*Ht dmsg_info_when(EMIT_EXTRA_DEBUG_MESSAGE) << " 4. get Compliance " ; - helper::ScopedAdvancedTimer getComplianceTimer("Get Compliance"); + SCOPED_TIMER_VARNAME(getComplianceTimer, "Get Compliance"); for (const auto cc : constraintCorrections) { cc->addComplianceInConstraintSpace(core::constraintparams::defaultInstance(), getCP()->getW()); @@ -507,7 +507,7 @@ void ConstraintAnimationLoop::correctiveMotion(const core::ExecParams* params, s dmsg_info_when(EMIT_EXTRA_DEBUG_MESSAGE) <<"constraintCorrections motion is called" ; - helper::ScopedAdvancedTimer correctiveMotionTimer("Corrective Motion"); + SCOPED_TIMER_VARNAME(correctiveMotionTimer, "Corrective Motion"); if(d_schemeCorrection.getValue()) { @@ -637,7 +637,7 @@ void ConstraintAnimationLoop::step ( const core::ExecParams* params, SReal dt ) // Update the BehaviorModels => to be removed ? // Required to allow the RayPickInteractor interaction { - helper::ScopedAdvancedTimer behaviorUpdateTimer("BehaviorUpdate"); + SCOPED_TIMER_VARNAME(behaviorUpdateTimer, "BehaviorUpdate"); simulation::BehaviorUpdatePositionVisitor(params, dt).execute(node); } @@ -697,7 +697,7 @@ void ConstraintAnimationLoop::step ( const core::ExecParams* params, SReal dt ) } { - helper::ScopedAdvancedTimer gaussSeidelTimer("GaussSeidel"); + SCOPED_TIMER_VARNAME(gaussSeidelTimer, "GaussSeidel"); if (EMIT_EXTRA_DEBUG_MESSAGE) msg_info() << "Gauss-Seidel solver is called on problem of size " << CP.getSize() ; @@ -739,7 +739,7 @@ void ConstraintAnimationLoop::step ( const core::ExecParams* params, SReal dt ) } { - helper::ScopedAdvancedTimer updateMappingTimer("UpdateMapping"); + SCOPED_TIMER_VARNAME(updateMappingTimer, "UpdateMapping"); node->execute(params); sofa::helper::AdvancedTimer::step("UpdateMappingEndEvent"); @@ -752,7 +752,7 @@ void ConstraintAnimationLoop::step ( const core::ExecParams* params, SReal dt ) if (d_computeBoundingBox.getValue()) { - sofa::helper::ScopedAdvancedTimer updateBBoxTimer("UpdateBBox"); + SCOPED_TIMER_VARNAME(updateBBoxTimer, "UpdateBBox"); node->execute(params); } diff --git a/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp b/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp index 1a97344d081e..d701c75a4c66 100644 --- a/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp +++ b/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp @@ -383,7 +383,7 @@ void FreeMotionAnimationLoop::computeFreeMotion(const sofa::core::ExecParams* pa auto node = dynamic_cast(this->l_node.get()); { - sofa::helper::ScopedAdvancedTimer timer("FreeMotion"); + SCOPED_TIMER("FreeMotion"); simulation::SolveVisitor freeMotion(params, dt, true, d_parallelODESolving.getValue()); node->execute(&freeMotion); } @@ -394,7 +394,7 @@ void FreeMotionAnimationLoop::computeFreeMotion(const sofa::core::ExecParams* pa if (cparams.constOrder() == sofa::core::ConstraintParams::POS || cparams.constOrder() == sofa::core::ConstraintParams::POS_AND_VEL) { - sofa::helper::ScopedAdvancedTimer timer("freePosEqPosPlusFreeVelDt"); + SCOPED_TIMER("freePosEqPosPlusFreeVelDt"); MechanicalVOpVisitor freePosEqPosPlusFreeVelDt(params, freePos, pos, freeVel, dt); freePosEqPosPlusFreeVelDt.setMapped(true); node->executeVisitor(&freePosEqPosPlusFreeVelDt); diff --git a/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/MultiStepAnimationLoop.cpp b/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/MultiStepAnimationLoop.cpp index 3ac3187c7495..53540049758d 100644 --- a/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/MultiStepAnimationLoop.cpp +++ b/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/MultiStepAnimationLoop.cpp @@ -65,7 +65,7 @@ void MultiStepAnimationLoop::step(const sofa::core::ExecParams* params, SReal dt if (dt == 0) dt = node->getDt(); - helper::ScopedAdvancedTimer animationStepTimer("AnimationStep"); + SCOPED_TIMER_VARNAME(animationStepTimer, "AnimationStep"); #ifdef SOFA_DUMP_VISITOR_INFO simulation::Visitor::printNode("Step"); @@ -122,7 +122,7 @@ void MultiStepAnimationLoop::step(const sofa::core::ExecParams* params, SReal dt //Visual Information update: Ray Pick add a MechanicalMapping used as VisualMapping { - helper::ScopedAdvancedTimer updateMappingTimer("UpdateMapping"); + SCOPED_TIMER_VARNAME(updateMappingTimer, "UpdateMapping"); node->execute(params); } { @@ -133,7 +133,7 @@ void MultiStepAnimationLoop::step(const sofa::core::ExecParams* params, SReal dt if (d_computeBoundingBox.getValue()) { - sofa::helper::ScopedAdvancedTimer timer("UpdateBBox"); + SCOPED_TIMER("UpdateBBox"); node->execute(params); } diff --git a/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/MultiTagAnimationLoop.cpp b/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/MultiTagAnimationLoop.cpp index 7526ae22bb19..6fb06c025503 100644 --- a/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/MultiTagAnimationLoop.cpp +++ b/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/MultiTagAnimationLoop.cpp @@ -71,7 +71,7 @@ void MultiTagAnimationLoop::step(const sofa::core::ExecParams* params, SReal dt) { auto node = dynamic_cast(this->l_node.get()); - helper::ScopedAdvancedTimer animationStepTimer("AnimationStep"); + SCOPED_TIMER_VARNAME(animationStepTimer, "AnimationStep"); #ifdef SOFA_DUMP_VISITOR_INFO simulation::Visitor::printNode("Step"); @@ -124,7 +124,7 @@ void MultiTagAnimationLoop::step(const sofa::core::ExecParams* params, SReal dt) //Visual Information update: Ray Pick add a MechanicalMapping used as VisualMapping { - helper::ScopedAdvancedTimer updateMappingTimer("UpdateMapping"); + SCOPED_TIMER_VARNAME(updateMappingTimer, "UpdateMapping"); node->execute(params); } { @@ -135,7 +135,7 @@ void MultiTagAnimationLoop::step(const sofa::core::ExecParams* params, SReal dt) if (d_computeBoundingBox.getValue()) { - sofa::helper::ScopedAdvancedTimer timer("UpdateBBox"); + SCOPED_TIMER("UpdateBBox"); node->execute(params); } diff --git a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/CollisionPipeline.cpp b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/CollisionPipeline.cpp index 7727761ff6fc..66118e003017 100644 --- a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/CollisionPipeline.cpp +++ b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/CollisionPipeline.cpp @@ -258,7 +258,7 @@ void CollisionPipeline::doCollisionResponse() << "Create Contacts " << contactManager->getName() ; { - helper::ScopedAdvancedTimer createContactsTimer("CreateContacts"); + SCOPED_TIMER_VARNAME(createContactsTimer, "CreateContacts"); contactManager->createContacts(narrowPhaseDetection->getDetectionOutputs()); } @@ -270,7 +270,7 @@ void CollisionPipeline::doCollisionResponse() type::vector notStaticContacts; { - helper::ScopedAdvancedTimer createStaticObjectsResponseTimer("CreateStaticObjectsResponse"); + SCOPED_TIMER_VARNAME(createStaticObjectsResponseTimer, "CreateStaticObjectsResponse"); for (const auto& contact : contacts) { const auto collisionModels = contact->getCollisionModels(); diff --git a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/DirectSAPNarrowPhase.cpp b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/DirectSAPNarrowPhase.cpp index 8fb085394d90..267abd1fa24e 100644 --- a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/DirectSAPNarrowPhase.cpp +++ b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/DirectSAPNarrowPhase.cpp @@ -129,7 +129,7 @@ void DirectSAPNarrowPhase::endNarrowPhase() void DirectSAPNarrowPhase::checkNewCollisionModels() { - helper::ScopedAdvancedTimer scopeTimer("Direct SAP check new cm"); + SCOPED_TIMER_VARNAME(scopeTimer, "Direct SAP check new cm"); for (auto *cm : m_broadPhaseCollisionModels) { auto *last = cm->getLast(); @@ -190,7 +190,7 @@ int DirectSAPNarrowPhase::greatestVarianceAxis() const void DirectSAPNarrowPhase::updateBoxes() { - sofa::helper::ScopedAdvancedTimer scopeTimer("Direct SAP update boxes"); + SCOPED_TIMER_VARNAME(scopeTimer, "Direct SAP update boxes"); m_currentAxis = greatestVarianceAxis(); for (auto& dsapBox : m_boxes) { @@ -220,7 +220,7 @@ bool DirectSAPNarrowPhase::isSquaredDistanceLessThan(const DSAPBox &a, const DSA void DirectSAPNarrowPhase::cacheData() { - sofa::helper::ScopedAdvancedTimer scopeTimer("Direct SAP cache"); + SCOPED_TIMER_VARNAME(scopeTimer, "Direct SAP cache"); unsigned int i{ 0 }; for (const auto& box : m_boxes) @@ -241,13 +241,13 @@ void DirectSAPNarrowPhase::cacheData() void DirectSAPNarrowPhase::sortEndPoints() { - sofa::helper::ScopedAdvancedTimer scopeTimer("Direct SAP sort"); + SCOPED_TIMER_VARNAME(scopeTimer, "Direct SAP sort"); std::sort(m_sortedEndPoints.begin(), m_sortedEndPoints.end(), CompPEndPoint()); } void DirectSAPNarrowPhase::narrowCollisionDetectionFromSortedEndPoints() { - sofa::helper::ScopedAdvancedTimer scopeTimer("Direct SAP intersection"); + SCOPED_TIMER_VARNAME(scopeTimer, "Direct SAP intersection"); int nbInvestigatedPairs{ 0 }; std::list activeBoxes;//active boxes are the one that we encoutered only their min (end point), so if there are two boxes b0 and b1, diff --git a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/IncrSAP.cpp b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/IncrSAP.cpp index f10191cdf9bc..d6fa4539d685 100644 --- a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/IncrSAP.cpp +++ b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/IncrSAP.cpp @@ -370,7 +370,7 @@ void IncrSAP::boxPrune(){ const int axis1 = (1 << _cur_axis) & 3; const int axis2 = (1 << axis1) & 3; - helper::ScopedAdvancedTimer timer("Box Prune SAP intersection"); + SCOPED_TIMER("Box Prune SAP intersection"); std::deque active_boxes; // active boxes are the one that we encoutered only their min (end point), so if there are two boxes b0 and b1, // if we encounter b1_min as b0_min < b1_min, on the current axis, the two boxes intersect : b0_min--------------------b0_max diff --git a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.cpp b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.cpp index f8fd5e4834ec..3d317311b6ee 100644 --- a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.cpp @@ -170,7 +170,7 @@ void GenericConstraintSolver::cleanup() bool GenericConstraintSolver::prepareStates(const core::ConstraintParams *cParams, MultiVecId /*res1*/, MultiVecId /*res2*/) { - sofa::helper::ScopedAdvancedTimer vtimer("PrepareStates"); + SCOPED_TIMER_VARNAME(vtimer, "PrepareStates"); last_cp = current_cp; @@ -204,7 +204,7 @@ bool GenericConstraintSolver::buildSystem(const core::ConstraintParams *cParams, unsigned int numConstraints = 0; { - helper::ScopedAdvancedTimer timer("Accumulate Constraint"); + SCOPED_TIMER("Accumulate Constraint"); auto* context = getContext(); @@ -225,12 +225,12 @@ bool GenericConstraintSolver::buildSystem(const core::ConstraintParams *cParams, current_cp->clear(numConstraints); { - sofa::helper::ScopedAdvancedTimer getConstraintValueTimer("Get Constraint Value"); + SCOPED_TIMER_VARNAME(getConstraintValueTimer, "Get Constraint Value"); MechanicalGetConstraintViolationVisitor(cParams, ¤t_cp->dFree).execute(getContext()); } { - sofa::helper::ScopedAdvancedTimer getConstraintResolutionsTimer("Get Constraint Resolutions"); + SCOPED_TIMER_VARNAME(getConstraintResolutionsTimer, "Get Constraint Resolutions"); MechanicalGetConstraintResolutionVisitor(cParams, current_cp->constraintsResolutions).execute(getContext()); } @@ -354,7 +354,7 @@ void GenericConstraintSolver::ComplianceWrapper::assembleMatrix() const void GenericConstraintSolver::buildSystem_matrixAssembly(const core::ConstraintParams *cParams) { - sofa::helper::ScopedAdvancedTimer getComplianceTimer("Get Compliance"); + SCOPED_TIMER_VARNAME(getComplianceTimer, "Get Compliance"); dmsg_info() <<" computeCompliance in " << l_constraintCorrections.size()<< " constraintCorrections" ; const bool multithreading = d_multithreading.getValue(); @@ -450,13 +450,13 @@ bool GenericConstraintSolver::solveSystem(const core::ConstraintParams * /*cPara msg_info() << tmp.str() ; } - sofa::helper::ScopedAdvancedTimer gaussSeidelTimer("ConstraintsGaussSeidel"); + SCOPED_TIMER_VARNAME(gaussSeidelTimer, "ConstraintsGaussSeidel"); current_cp->gaussSeidel(0, this); break; } // UnbuiltGaussSeidel case 1: { - sofa::helper::ScopedAdvancedTimer unbuiltGaussSeidelTimer("ConstraintsUnbuiltGaussSeidel"); + SCOPED_TIMER_VARNAME(unbuiltGaussSeidelTimer, "ConstraintsUnbuiltGaussSeidel"); current_cp->unbuiltGaussSeidel(0, this); break; } @@ -513,7 +513,7 @@ bool GenericConstraintSolver::applyCorrection(const core::ConstraintParams *cPar msg_info() << "KeepContactForces done" ; { - helper::ScopedAdvancedTimer timer("Compute And Apply Motion Correction"); + SCOPED_TIMER("Compute And Apply Motion Correction"); if (cParams->constOrder() == core::ConstraintParams::POS_AND_VEL) { @@ -581,7 +581,7 @@ bool GenericConstraintSolver::applyCorrection(const core::ConstraintParams *cPar msg_info() << "Compute And Apply Motion Correction in constraintCorrection done" ; { - helper::ScopedAdvancedTimer timer("Store Constraint Lambdas"); + SCOPED_TIMER("Store Constraint Lambdas"); /// Some constraint correction schemes may have written the constraint motion space lambda in the lambdaId VecId. /// In order to be sure that we are not accumulating things twice, we need to clear. diff --git a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.cpp b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.cpp index 6180bd408e92..9a44653e3b35 100644 --- a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.cpp @@ -116,7 +116,7 @@ bool LCPConstraintSolver::prepareStates(const core::ConstraintParams * /*cParams msg_info() <<" propagate DXn performed - collision called" ; - helper::ScopedAdvancedTimer resetContactForceTimer("resetContactForce"); + SCOPED_TIMER_VARNAME(resetContactForceTimer, "resetContactForce"); for (const auto cc : l_constraintCorrections) { @@ -137,13 +137,13 @@ bool LCPConstraintSolver::buildSystem(const core::ConstraintParams * /*cParams*/ if(build_lcp.getValue()) { - helper::ScopedAdvancedTimer buildTimer("build_LCP"); + SCOPED_TIMER_VARNAME(buildTimer, "build_LCP"); build_LCP(); } else { - helper::ScopedAdvancedTimer buildTimer("build_problem"); + SCOPED_TIMER_VARNAME(buildTimer, "build_problem"); build_problem_info(); } @@ -170,7 +170,7 @@ bool LCPConstraintSolver::solveSystem(const core::ConstraintParams * /*cParams*/ if (multi_grid.getValue()) { { - helper::ScopedAdvancedTimer timer("ConstraintsMerge"); + SCOPED_TIMER("ConstraintsMerge"); MultigridConstraintsMerge(); } @@ -182,7 +182,7 @@ bool LCPConstraintSolver::solveSystem(const core::ConstraintParams * /*cParams*/ graph_levels.clear(); { - helper::ScopedAdvancedTimer timer("NLCP MultiGrid"); + SCOPED_TIMER("NLCP MultiGrid"); helper::nlcp_multiGrid_Nlevels(_numConstraints, _dFree->ptr(), _W->lptr(), _result->ptr(), _mu, _tol, _maxIt, initial_guess.getValue(), hierarchy_contact_group, hierarchy_num_group, hierarchy_constraint_group, hierarchy_constraint_group_fact, notMuted(), &graph_residuals, &graph_levels, &graph_violations); } @@ -196,7 +196,7 @@ bool LCPConstraintSolver::solveSystem(const core::ConstraintParams * /*cParams*/ graph_violations.clear(); { - helper::ScopedAdvancedTimer timer("NLCP GaussSeidel"); + SCOPED_TIMER("NLCP GaussSeidel"); helper::nlcp_gaussseidel(_numConstraints, _dFree->ptr(), _W->lptr(), _result->ptr(), _mu, _tol, _maxIt, initial_guess.getValue(), notMuted(), _minW, _maxF, &graph_error, &graph_violations); } @@ -208,7 +208,7 @@ bool LCPConstraintSolver::solveSystem(const core::ConstraintParams * /*cParams*/ graph_error.clear(); { - helper::ScopedAdvancedTimer timer("LCP GaussSeidel"); + SCOPED_TIMER("LCP GaussSeidel"); helper::gaussSeidelLCP1(_numConstraints, _dFree->ptr(), _W->lptr(), _result->ptr(), _tol, _maxIt, _minW, _maxF, &graph_error); } if (notMuted()) @@ -224,7 +224,7 @@ bool LCPConstraintSolver::solveSystem(const core::ConstraintParams * /*cParams*/ graph_error.clear(); { - helper::ScopedAdvancedTimer timer("NLCP GaussSeidel Unbuild"); + SCOPED_TIMER("NLCP GaussSeidel Unbuild"); gaussseidel_unbuilt(_dFree->ptr(), _result->ptr(), &graph_error); } @@ -267,7 +267,7 @@ bool LCPConstraintSolver::applyCorrection(const core::ConstraintParams * /*cPara dmsg_info() << "keepContactForces done" ; { - helper::ScopedAdvancedTimer timer("Apply Contact Force"); + SCOPED_TIMER("Apply Contact Force"); for (unsigned int i = 0; i < l_constraintCorrections.size(); i++) { if (!constraintCorrectionIsActive[i]) continue; @@ -283,14 +283,14 @@ bool LCPConstraintSolver::applyCorrection(const core::ConstraintParams * /*cPara void LCPConstraintSolver::resetConstraints(core::ConstraintParams cparams) { - helper::ScopedAdvancedTimer resetConstraintsTimer("Reset Constraint"); + SCOPED_TIMER_VARNAME(resetConstraintsTimer, "Reset Constraint"); MechanicalResetConstraintVisitor resetCtr(&cparams); resetCtr.execute(getContext()); } void LCPConstraintSolver::buildConstraintMatrix(core::ConstraintParams cparams) { - helper::ScopedAdvancedTimer buildConstraintMatrixTimer("Build Constraint Matrix"); + SCOPED_TIMER_VARNAME(buildConstraintMatrixTimer, "Build Constraint Matrix"); MechanicalBuildConstraintMatrix buildConstraintMatrix(&cparams, cparams.j(), _numConstraints ); buildConstraintMatrix.execute(getContext()); @@ -298,7 +298,7 @@ void LCPConstraintSolver::buildConstraintMatrix(core::ConstraintParams cparams) void LCPConstraintSolver::accumulateMatrixDeriv(core::ConstraintParams cparams) { - helper::ScopedAdvancedTimer accumulateMatrixDerivTimer("Accumulate Matrix Deriv"); + SCOPED_TIMER_VARNAME(accumulateMatrixDerivTimer, "Accumulate Matrix Deriv"); MechanicalAccumulateMatrixDeriv accumulateMatrixDeriv(&cparams, cparams.j()); accumulateMatrixDeriv.execute(getContext()); @@ -332,7 +332,7 @@ void LCPConstraintSolver::getConstraintInfo(core::ConstraintParams cparams) if ((initial_guess.getValue() || multi_grid.getValue() || showLevels.getValue()) && (_numConstraints != 0)) { { - helper::ScopedAdvancedTimer timer("Get Constraint Info"); + SCOPED_TIMER("Get Constraint Info"); MechanicalGetConstraintInfoVisitor(&cparams, hierarchy_constraintBlockInfo[0], hierarchy_constraintIds[0], hierarchy_constraintPositions[0], hierarchy_constraintDirections[0], hierarchy_constraintAreas[0]).execute(getContext()); } if (initial_guess.getValue()) @@ -342,7 +342,7 @@ void LCPConstraintSolver::getConstraintInfo(core::ConstraintParams cparams) void LCPConstraintSolver::addComplianceInConstraintSpace(core::ConstraintParams cparams) { - helper::ScopedAdvancedTimer timer("Get Compliance"); + SCOPED_TIMER("Get Compliance"); dmsg_info() <<" computeCompliance in " << l_constraintCorrections.size()<< " constraintCorrections" ; @@ -377,7 +377,7 @@ void LCPConstraintSolver::build_LCP() lcp->clear(_numConstraints); { - helper::ScopedAdvancedTimer getConstraintValueTimer("Get Constraint Value"); + SCOPED_TIMER_VARNAME(getConstraintValueTimer, "Get Constraint Value"); MechanicalGetConstraintViolationVisitor(&cparams, _dFree).execute(getContext()); } @@ -727,7 +727,7 @@ void LCPConstraintSolver::build_problem_info() _Wdiag.resize(_numConstraints,_numConstraints); { - helper::ScopedAdvancedTimer getConstraintValueTimer("Get Constraint Value"); + SCOPED_TIMER_VARNAME(getConstraintValueTimer, "Get Constraint Value"); MechanicalGetConstraintViolationVisitor(&cparams, _dFree).execute(getContext()); } @@ -974,7 +974,7 @@ int LCPConstraintSolver::nlcp_gaussseidel_unbuilt(SReal *dfree, SReal *f, std::v buildDiagonalTimer.reset(); - helper::ScopedAdvancedTimer gaussSeidelTimer("GAUSS_SEIDEL"); + SCOPED_TIMER_VARNAME(gaussSeidelTimer, "GAUSS_SEIDEL"); SReal error = 0; SReal dn, dt, ds, fn, ft, fs, fn0; @@ -1204,7 +1204,7 @@ int LCPConstraintSolver::lcp_gaussseidel_unbuilt(SReal *dfree, SReal *f, std::ve } buildDiagonalTimer.reset(); - sofa::helper::ScopedAdvancedTimer gaussSeidelTimer("GAUSS_SEIDEL"); + SCOPED_TIMER_VARNAME(gaussSeidelTimer, "GAUSS_SEIDEL"); SReal error = 0; SReal dn, fn, fn0; diff --git a/Sofa/Component/Diffusion/src/sofa/component/diffusion/TetrahedronDiffusionFEMForceField.inl b/Sofa/Component/Diffusion/src/sofa/component/diffusion/TetrahedronDiffusionFEMForceField.inl index 960ae9d9addd..add068861507 100644 --- a/Sofa/Component/Diffusion/src/sofa/component/diffusion/TetrahedronDiffusionFEMForceField.inl +++ b/Sofa/Component/Diffusion/src/sofa/component/diffusion/TetrahedronDiffusionFEMForceField.inl @@ -309,7 +309,7 @@ void TetrahedronDiffusionFEMForceField::setDiffusionCoefficient(const template void TetrahedronDiffusionFEMForceField::addForce (const core::MechanicalParams* /*mparams*/, DataVecDeriv& dataf, const DataVecCoord& datax, const DataVecDeriv& /*v*/) { - helper::ScopedAdvancedTimer timer("addForceDiffusion"); + SCOPED_TIMER("addForceDiffusion"); auto f = sofa::helper::getWriteOnlyAccessor(dataf); const VecCoord& x = datax.getValue(); @@ -334,7 +334,7 @@ void TetrahedronDiffusionFEMForceField::addForce (const core::Mechani template void TetrahedronDiffusionFEMForceField::addDForce(const sofa::core::MechanicalParams* mparams, DataVecDeriv& datadF , const DataVecDeriv& datadX) { - helper::ScopedAdvancedTimer timer("addDForceDiffusion"); + SCOPED_TIMER("addDForceDiffusion"); auto df = sofa::helper::getWriteOnlyAccessor(datadF); const VecDeriv& dx=datadX.getValue(); Real kFactor = mparams->kFactor(); @@ -359,7 +359,7 @@ void TetrahedronDiffusionFEMForceField::addDForce(const sofa::core::M template void TetrahedronDiffusionFEMForceField::addKToMatrix(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) { - helper::ScopedAdvancedTimer timer("addKToMatrix"); + SCOPED_TIMER("addKToMatrix"); const auto N = defaulttype::DataTypeInfo::size(); sofa::core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate); sofa::linearalgebra::BaseMatrix* mat = r.matrix; diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/AsyncSparseLDLSolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/AsyncSparseLDLSolver.inl index 9cb39dc3c183..2965a02d60f2 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/AsyncSparseLDLSolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/AsyncSparseLDLSolver.inl @@ -42,7 +42,7 @@ void AsyncSparseLDLSolver::setSystemMBKMatrix( { if (isAsyncFactorizationFinished() || !m_asyncResult.valid()) { - sofa::helper::ScopedAdvancedTimer setSystemMBKMatrixTimer("setSystemMBKMatrix"); + SCOPED_TIMER_VARNAME(setSystemMBKMatrixTimer, "setSystemMBKMatrix"); Inherit1::setSystemMBKMatrix(mparams); m_hasUpdatedMatrix = true; } @@ -51,7 +51,7 @@ void AsyncSparseLDLSolver::setSystemMBKMatrix( template void AsyncSparseLDLSolver::solveSystem() { - sofa::helper::ScopedAdvancedTimer invertDataCopyTimer("AsyncSolve"); + SCOPED_TIMER_VARNAME(invertDataCopyTimer, "AsyncSolve"); if (newInvertDataReady) { diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/EigenDirectSparseSolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/EigenDirectSparseSolver.inl index a74a3795d558..6795096feaf6 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/EigenDirectSparseSolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/EigenDirectSparseSolver.inl @@ -61,7 +61,7 @@ void EigenDirectSparseSolver ::invert(Matrix& A) { { - sofa::helper::ScopedAdvancedTimer copyTimer("copyMatrixData"); + SCOPED_TIMER_VARNAME(copyTimer, "copyMatrixData"); Mfiltered.copyNonZeros(A); Mfiltered.compress(); } @@ -76,7 +76,7 @@ void EigenDirectSparseSolver if (analyzePattern) { - sofa::helper::ScopedAdvancedTimer patternAnalysisTimer("patternAnalysis"); + SCOPED_TIMER_VARNAME(patternAnalysisTimer, "patternAnalysis"); std::visit([this](auto&& solver) { solver.analyzePattern(*m_map); @@ -87,7 +87,7 @@ void EigenDirectSparseSolver } { - sofa::helper::ScopedAdvancedTimer factorizeTimer("factorization"); + SCOPED_TIMER_VARNAME(factorizeTimer, "factorization"); std::visit([this](auto&& solver) { solver.factorize(*m_map); diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SVDLinearSolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SVDLinearSolver.inl index 33cd9752722e..fc57ecbbfd88 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SVDLinearSolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SVDLinearSolver.inl @@ -50,7 +50,7 @@ void SVDLinearSolver::solve(Matrix& M, Vector& x, Vector& b) simulation::Visitor::printComment("SVD"); #endif - sofa::helper::ScopedAdvancedTimer svdSolveTimer("Solve-SVD"); + SCOPED_TIMER_VARNAME(svdSolveTimer, "Solve-SVD"); const bool verbose = f_verbose.getValue(); @@ -61,7 +61,7 @@ void SVDLinearSolver::solve(Matrix& M, Vector& x, Vector& b) EigenMatrixX m(M.rowSize(),M.colSize()); EigenVectorX rhs(M.rowSize()); { - sofa::helper::ScopedAdvancedTimer convertTimer("convertToEigen"); + SCOPED_TIMER_VARNAME(convertTimer, "convertToEigen"); for(unsigned i=0; i<(unsigned)M.rowSize(); i++ ) { for( unsigned j=0; j<(unsigned)M.colSize(); j++ ) @@ -76,7 +76,7 @@ void SVDLinearSolver::solve(Matrix& M, Vector& x, Vector& b) /// Compute the SVD decomposition and the condition number Eigen::JacobiSVD svd; { - sofa::helper::ScopedAdvancedTimer svdDecompositionTimer("SVDDecomposition"); + SCOPED_TIMER_VARNAME(svdDecompositionTimer, "SVDDecomposition"); svd.compute(m, Eigen::ComputeThinU | Eigen::ComputeThinV); f_conditionNumber.setValue( (Real)(svd.singularValues()(0) / svd.singularValues()(M.rowSize()-1)) ); } @@ -96,7 +96,7 @@ void SVDLinearSolver::solve(Matrix& M, Vector& x, Vector& b) /// Solve the equation system and copy the solution to the SOFA vector { - sofa::helper::ScopedAdvancedTimer solveSvdTimer("solveFromSVD"); + SCOPED_TIMER_VARNAME(solveSvdTimer, "solveFromSVD"); EigenVectorX Ut_b = svd.matrixU().transpose() * rhs; EigenVectorX S_Ut_b(M.colSize()); for( unsigned i=0; i<(unsigned)M.colSize(); i++ ) /// product with the diagonal matrix, using the threshold for near-null values diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.inl index 16506cf9e5f5..70190cd92c58 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.inl @@ -46,7 +46,7 @@ void SparseCholeskySolver::solve (Matrix& /*M*/, Vector& x, Vec { const int n = A.n; - sofa::helper::ScopedAdvancedTimer solveTimer("solve"); + SCOPED_TIMER_VARNAME(solveTimer, "solve"); switch( d_typePermutation.getValue().getSelectedId() ) { @@ -108,7 +108,7 @@ void SparseCholeskySolver::invert(Matrix& M) tmp.resize(A.n); { - sofa::helper::ScopedAdvancedTimer factorization_permTimer("factorization_perm"); + SCOPED_TIMER_VARNAME(factorization_permTimer, "factorization_perm"); notSameShape = compareMatrixShape( A.n , A.p , A.i, Previous_colptr.size()-1 , Previous_colptr.data() , Previous_rowind.data() ); diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl index 0b5e492fd3ab..feaaf6dc0883 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl @@ -110,7 +110,7 @@ void SparseLDLSolver::parse(sofa::core::object template void SparseLDLSolver::solve (Matrix& M, Vector& z, Vector& r) { - sofa::helper::ScopedAdvancedTimer solveTimer("solve"); + SCOPED_TIMER_VARNAME(solveTimer, "solve"); Inherit::solve_cpu(z.ptr(), r.ptr(), (InvertData *) this->getMatrixInvertData(&M)); } diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolverImpl.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolverImpl.h index ad6551346ab7..cf1d51c1f4aa 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolverImpl.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolverImpl.h @@ -293,7 +293,7 @@ protected : // we test if the matrix has the same struct as previous factorized matrix if (data->new_factorization_needed || !d_precomputeSymbolicDecomposition.getValue() ) { - sofa::helper::ScopedAdvancedTimer factorizationTimer("symbolic_factorization"); + SCOPED_TIMER_VARNAME(factorizationTimer, "symbolic_factorization"); msg_info() << "Recomputing new factorization" ; data->perm.clear();data->perm.fastResize(data->n); @@ -336,7 +336,7 @@ protected : //Numeric Factorization { - sofa::helper::ScopedAdvancedTimer factorizationTimer("numeric_factorization"); + SCOPED_TIMER_VARNAME(factorizationTimer, "numeric_factorization"); LDL_numeric(data->n, M_colptr, M_rowind, M_values, colptr, rowind, values, D, data->perm.data(), data->invperm.data(), data->Parent.data()); diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.inl index e15f504c7252..7c0339024f26 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.inl @@ -68,7 +68,7 @@ void SparseLUSolver::solve (Matrix& M, Vector& x const int n = invertData->A.n; { - sofa::helper::ScopedAdvancedTimer solveTimer("solve"); + SCOPED_TIMER_VARNAME(solveTimer, "solve"); switch( d_typePermutation.getValue().getSelectedId() ) { @@ -151,7 +151,7 @@ void SparseLUSolver::invert(Matrix& M) invertData->tmp = (Real *) cs_malloc (invertData->A.n, sizeof (Real)) ; { - sofa::helper::ScopedAdvancedTimer factorizationTimer("factorization"); + SCOPED_TIMER_VARNAME(factorizationTimer, "factorization"); switch( d_typePermutation.getValue().getSelectedId() ) { case 0://None->Identity diff --git a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/CGLinearSolver.inl b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/CGLinearSolver.inl index e623f97e56da..7903e581465d 100644 --- a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/CGLinearSolver.inl +++ b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/CGLinearSolver.inl @@ -85,7 +85,7 @@ void CGLinearSolver::resetSystem() template void CGLinearSolver::setSystemMBKMatrix(const sofa::core::MechanicalParams* mparams) { - sofa::helper::ScopedAdvancedTimer timer("CG-setSystemMBKMatrix"); + SCOPED_TIMER("CG-setSystemMBKMatrix"); Inherit::setSystemMBKMatrix(mparams); } diff --git a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/ShewchukPCGLinearSolver.inl b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/ShewchukPCGLinearSolver.inl index ec0cc3b6821a..083163bd18fa 100644 --- a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/ShewchukPCGLinearSolver.inl +++ b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/ShewchukPCGLinearSolver.inl @@ -94,7 +94,7 @@ void ShewchukPCGLinearSolver::setSystemMBKMatrix(const core::Me sofa::helper::AdvancedTimer::valSet("PCG::buildMBK", 1); { - helper::ScopedAdvancedTimer timer("PCG::setSystemMBKMatrix"); + SCOPED_TIMER("PCG::setSystemMBKMatrix"); Inherit::setSystemMBKMatrix(mparams); } @@ -109,7 +109,7 @@ void ShewchukPCGLinearSolver::setSystemMBKMatrix(const core::Me else if (f_build_precond.getValue()) { sofa::helper::AdvancedTimer::valSet("PCG::PrecondBuildMBK", 1); - helper::ScopedAdvancedTimer mbkTimer("PCG::PrecondSetSystemMBKMatrix"); + SCOPED_TIMER_VARNAME(mbkTimer, "PCG::PrecondSetSystemMBKMatrix"); if (f_update_step.getValue()>0) { @@ -155,7 +155,7 @@ void ShewchukPCGLinearSolver::handleEvent(sofa::core::objectmodel template void ShewchukPCGLinearSolver::solve (Matrix& M, Vector& x, Vector& b) { - helper::ScopedAdvancedTimer solveTimer("PCGLinearSolver::solve"); + SCOPED_TIMER_VARNAME(solveTimer, "PCGLinearSolver::solve"); std::map < std::string, sofa::type::vector >& graph = * f_graph.beginEdit(); // sofa::type::vector& graph_error = graph["Error"]; @@ -181,7 +181,7 @@ void ShewchukPCGLinearSolver::solve (Matrix& M, Vector& x, Vect if (apply_precond) { - helper::ScopedAdvancedTimer applyPrecondTimer("PCGLinearSolver::apply Precond"); + SCOPED_TIMER_VARNAME(applyPrecondTimer, "PCGLinearSolver::apply Precond"); l_preconditioner.get()->setSystemLHVector(w); l_preconditioner.get()->setSystemRHVector(r); l_preconditioner.get()->solveSystem(); @@ -206,7 +206,7 @@ void ShewchukPCGLinearSolver::solve (Matrix& M, Vector& x, Vect if (apply_precond) { - helper::ScopedAdvancedTimer applyPrecondTimer("PCGLinearSolver::apply Precond"); + SCOPED_TIMER_VARNAME(applyPrecondTimer, "PCGLinearSolver::apply Precond"); l_preconditioner.get()->setSystemLHVector(s); l_preconditioner.get()->setSystemRHVector(r); l_preconditioner.get()->solveSystem(); diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl index 88ee6f21f9ba..028b592c046f 100644 --- a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl @@ -111,10 +111,10 @@ void MatrixLinearSystem::assembleSystem(const core::Mechanical return; } - sofa::helper::ScopedAdvancedTimer assembleSystemTimer("AssembleSystem"); + SCOPED_TIMER_VARNAME(assembleSystemTimer, "AssembleSystem"); { - sofa::helper::ScopedAdvancedTimer buildMatricesTimer("buildMatrices"); + SCOPED_TIMER_VARNAME(buildMatricesTimer, "buildMatrices"); if (d_assembleStiffness.getValue()) { @@ -495,7 +495,7 @@ MatrixLinearSystem::getLocalMatrixMap() const template void MatrixLinearSystem::associateLocalMatrixToComponents(const core::MechanicalParams* mparams) { - sofa::helper::ScopedAdvancedTimer timer("InitializeSystem"); + SCOPED_TIMER("InitializeSystem"); m_needClearLocalMatrices.updateIfDirty(); if (m_needClearLocalMatrices.getValue()) @@ -510,7 +510,7 @@ void MatrixLinearSystem::associateLocalMatrixToComponents(cons m_discarder.m_globalMatrix = this->getSystemMatrix(); { - sofa::helper::ScopedAdvancedTimer resizeTimer("resizeSystem"); + SCOPED_TIMER_VARNAME(resizeTimer, "resizeSystem"); const auto rowSize = this->getSystemMatrix() ? this->getSystemMatrix()->rowSize() : 0; const auto colSize = this->getSystemMatrix() ? this->getSystemMatrix()->colSize() : 0; this->resizeSystem(totalSize); @@ -520,12 +520,12 @@ void MatrixLinearSystem::associateLocalMatrixToComponents(cons "System matrix is resized from " << rowSize << " x " << colSize << " to " << newRowSize << " x " << newColSize; } { - sofa::helper::ScopedAdvancedTimer clearSystemTimer("clearSystem"); + SCOPED_TIMER_VARNAME(clearSystemTimer, "clearSystem"); this->clearSystem(); } { - sofa::helper::ScopedAdvancedTimer localMatricesTimer("initializeLocalMatrices"); + SCOPED_TIMER_VARNAME(localMatricesTimer, "initializeLocalMatrices"); if (d_assembleMass.getValue()) { @@ -856,7 +856,7 @@ void MatrixLinearSystem::assembleMappedMatrices(const core::Me return; } - sofa::helper::ScopedAdvancedTimer buildMappedMatricesTimer("projectMappedMatrices"); + SCOPED_TIMER_VARNAME(buildMappedMatricesTimer, "projectMappedMatrices"); projectMappedMatrices(mparams); } @@ -864,7 +864,7 @@ template void MatrixLinearSystem::applyProjectiveConstraints(const core::MechanicalParams* mparams) { SOFA_UNUSED(mparams); - sofa::helper::ScopedAdvancedTimer applyProjectiveConstraintTimer("applyProjectiveConstraint"); + SCOPED_TIMER_VARNAME(applyProjectiveConstraintTimer, "applyProjectiveConstraint"); for (auto* constraint : this->m_projectiveConstraints) { if (constraint) diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/TypedMatrixLinearSystem.inl b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/TypedMatrixLinearSystem.inl index dd9a8a53b5a9..58fcf531f8a6 100644 --- a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/TypedMatrixLinearSystem.inl +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/TypedMatrixLinearSystem.inl @@ -40,7 +40,7 @@ void TypedMatrixLinearSystem::preAssembleSystem(const core::Me allocateSystem(); { - sofa::helper::ScopedAdvancedTimer mappingGraphTimer("getContributors"); + SCOPED_TIMER_VARNAME(mappingGraphTimer, "getContributors"); m_forceFields.clear(); m_masses.clear(); @@ -63,7 +63,7 @@ void TypedMatrixLinearSystem::preAssembleSystem(const core::Me } { - sofa::helper::ScopedAdvancedTimer mappingGraphTimer("buildMappingGraph"); + SCOPED_TIMER_VARNAME(mappingGraphTimer, "buildMappingGraph"); // build the mapping graph: this is used to know the relationship between the mechanical states and their associated components m_mappingGraph.build(mparams, getSolveContext()); } diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/EulerImplicitSolver.cpp b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/EulerImplicitSolver.cpp index 318a3ef70c3d..abe7c9cc798e 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/EulerImplicitSolver.cpp +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/EulerImplicitSolver.cpp @@ -112,7 +112,7 @@ void EulerImplicitSolver::solve(const core::ExecParams* params, SReal dt, sofa:: msg_info() << "trapezoidal factor = " << tr; { - helper::ScopedAdvancedTimer timer("ComputeForce"); + SCOPED_TIMER("ComputeForce"); mop->setImplicit(true); // this solver is implicit // compute the net forces at the beginning of the time step mop.computeForce(f); @@ -164,7 +164,7 @@ void EulerImplicitSolver::solve(const core::ExecParams* params, SReal dt, sofa:: #endif sofa::helper::AdvancedTimer::stepEnd ("MBKBuild"); { - helper::ScopedAdvancedTimer timer("MBKSolve"); + SCOPED_TIMER("MBKSolve"); matrix.solve(x, b); //Call to ODE resolution: x is the solution of the system} } #ifdef SOFA_DUMP_VISITOR_INFO @@ -260,16 +260,16 @@ void EulerImplicitSolver::solve(const core::ExecParams* params, SReal dt, sofa:: ops[1].second.push_back(std::make_pair(newVel.id(),h)); } - helper::ScopedAdvancedTimer updateVAndXTimer("UpdateVAndX"); + SCOPED_TIMER_VARNAME(updateVAndXTimer, "UpdateVAndX"); vop.v_multiop(ops); if (solveConstraint) { { - helper::ScopedAdvancedTimer correctVTimer("CorrectV"); + SCOPED_TIMER_VARNAME(correctVTimer, "CorrectV"); mop.solveConstraint(newVel,core::ConstraintParams::VEL); } { - helper::ScopedAdvancedTimer correctXTimer("CorrectX"); + SCOPED_TIMER_VARNAME(correctXTimer, "CorrectX"); mop.solveConstraint(newPos,core::ConstraintParams::POS); } } diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp index fb6bf3421fa6..f58dc8349417 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp @@ -164,7 +164,7 @@ void StaticSolver::solve(const sofa::core::ExecParams* params, SReal dt, sofa::c // # the residual with the updated right-hand side (the new load increment) # // ########################################################################### { - helper::ScopedAdvancedTimer computeForceTimer("ComputeForce"); + SCOPED_TIMER_VARNAME(computeForceTimer, "ComputeForce"); // Step 1 Assemble the force vector // 1. Clear the force vector (F := 0) diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/VariationalSymplecticSolver.cpp b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/VariationalSymplecticSolver.cpp index 8fe2f9ad5d06..ce068ad3e7d2 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/VariationalSymplecticSolver.cpp +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/VariationalSymplecticSolver.cpp @@ -123,12 +123,12 @@ void VariationalSymplecticSolver::solve(const core::ExecParams* params, SReal dt MultiVecDeriv acc(&vop, core::VecDerivId::dx()); acc.realloc(&vop, !d_threadSafeVisitor.getValue(), true); // dx is no longer allocated by default (but it will be deleted automatically by the mechanical objects) { - helper::ScopedAdvancedTimer timer("ComputeForce"); + SCOPED_TIMER("ComputeForce"); mop.computeForce(f); } { - helper::ScopedAdvancedTimer timer("AccFromF"); + SCOPED_TIMER("AccFromF"); f.peq(p,1.0/h); @@ -193,7 +193,7 @@ void VariationalSymplecticSolver::solve(const core::ExecParams* params, SReal dt // and matrix=-K+4/h^(2)M { - helper::ScopedAdvancedTimer timer("ComputeForce"); + SCOPED_TIMER("ComputeForce"); mop.computeForce(f); } @@ -215,12 +215,12 @@ void VariationalSymplecticSolver::solve(const core::ExecParams* params, SReal dt // add left term : matrix=-K+4/h^(2)M, but with dampings rK and rM { - helper::ScopedAdvancedTimer timer("MBKBuild"); + SCOPED_TIMER("MBKBuild"); matrix.setSystemMBKMatrix(MechanicalMatrix::K * (-1.0-4*rK/h) + MechanicalMatrix::M * (4.0/(h*h)+4*rM/h)); } { - helper::ScopedAdvancedTimer timer("MBKSolve"); + SCOPED_TIMER("MBKSolve"); // resolution of matrix*res=b matrix.solve(res, b); //Call to ODE resolution. } @@ -340,7 +340,7 @@ void VariationalSymplecticSolver::solve(const core::ExecParams* params, SReal dt sofa::helper::AdvancedTimer::stepEnd("CorrectV"); { - helper::ScopedAdvancedTimer timer("CorrectX"); + SCOPED_TIMER("CorrectX"); mop.solveConstraint(x_1,core::ConstraintParams::POS); } diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp index 643c38cb12a6..2034f387084f 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp @@ -55,7 +55,7 @@ void EulerExplicitSolver::solve(const core::ExecParams* params, sofa::core::MultiVecCoordId xResult, sofa::core::MultiVecDerivId vResult) { - sofa::helper::ScopedAdvancedTimer timer("EulerExplicitSolve"); + SCOPED_TIMER("EulerExplicitSolve"); // Create the vector and mechanical operations tools. These are used to execute special operations (multiplication, // additions, etc.) on multi-vectors (a vector that is stored in different buffers inside the mechanical objects) @@ -113,7 +113,7 @@ void EulerExplicitSolver::updateState(sofa::simulation::common::VectorOperations const sofa::core::behavior::MultiVecDeriv& acc, SReal dt) const { - sofa::helper::ScopedAdvancedTimer timer("updateState"); + SCOPED_TIMER("updateState"); // Initialize the set of multi-vectors computed by this solver // "xResult" could be "position()" or "freePosition()" depending on the @@ -262,7 +262,7 @@ void EulerExplicitSolver::parse(sofa::core::objectmodel::BaseObjectDescription* void EulerExplicitSolver::addSeparateGravity(sofa::simulation::common::MechanicalOperations* mop, SReal dt, core::MultiVecDerivId v) { - sofa::helper::ScopedAdvancedTimer timer("addSeparateGravity"); + SCOPED_TIMER("addSeparateGravity"); /// Calls the "addGravityToV" method of every BaseMass objects found in the current /// context tree, if the BaseMass object has the m_separateGravity flag set to true. @@ -272,7 +272,7 @@ void EulerExplicitSolver::addSeparateGravity(sofa::simulation::common::Mechanica void EulerExplicitSolver::computeForce(sofa::simulation::common::MechanicalOperations* mop, core::MultiVecDerivId f) { - sofa::helper::ScopedAdvancedTimer timer("ComputeForce"); + SCOPED_TIMER("ComputeForce"); // 1. Clear the force vector (F := 0) // 2. Go down in the current context tree calling addForce on every forcefields @@ -282,7 +282,7 @@ void EulerExplicitSolver::computeForce(sofa::simulation::common::MechanicalOpera void EulerExplicitSolver::computeAcceleration(sofa::simulation::common::MechanicalOperations* mop, core::MultiVecDerivId acc, core::ConstMultiVecDerivId f) { - sofa::helper::ScopedAdvancedTimer timer("AccFromF"); + SCOPED_TIMER("AccFromF"); // acc = M^-1 f // Since it requires the inverse of the mass matrix, this method is @@ -294,7 +294,7 @@ void EulerExplicitSolver::computeAcceleration(sofa::simulation::common::Mechanic void EulerExplicitSolver::projectResponse(sofa::simulation::common::MechanicalOperations* mop, core::MultiVecDerivId vecId) { - sofa::helper::ScopedAdvancedTimer timer("projectResponse"); + SCOPED_TIMER("projectResponse"); // Calls the "projectResponse" method of every BaseProjectiveConstraintSet objects found in the // current context tree. An example of such constraint set is the FixedConstraint. In this case, @@ -304,7 +304,7 @@ void EulerExplicitSolver::projectResponse(sofa::simulation::common::MechanicalOp void EulerExplicitSolver::solveConstraints(sofa::simulation::common::MechanicalOperations* mop, core::MultiVecDerivId acc) { - sofa::helper::ScopedAdvancedTimer timer("solveConstraint"); + SCOPED_TIMER("solveConstraint"); // Calls "solveConstraint" method of every ConstraintSolver objects found in the current context tree. mop->solveConstraint(acc, core::ConstraintParams::ACC); @@ -312,7 +312,7 @@ void EulerExplicitSolver::solveConstraints(sofa::simulation::common::MechanicalO void EulerExplicitSolver::assembleSystemMatrix(core::behavior::MultiMatrix* matrix) { - sofa::helper::ScopedAdvancedTimer timer("MBKBuild"); + SCOPED_TIMER("MBKBuild"); // The MechanicalMatrix::M is a simple structure that stores three floats called factors: m, b and k. // In the case of MechanicalMatrix::M: @@ -334,7 +334,7 @@ void EulerExplicitSolver::assembleSystemMatrix(core::behavior::MultiMatrix* matrix, core::MultiVecDerivId solution, core::MultiVecDerivId rhs) { - sofa::helper::ScopedAdvancedTimer timer("MBKSolve"); + SCOPED_TIMER("MBKSolve"); matrix->solve(solution, rhs); } diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/StandardTetrahedralFEMForceField.inl b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/StandardTetrahedralFEMForceField.inl index 2b9debaba82c..1a4834aa0d5e 100644 --- a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/StandardTetrahedralFEMForceField.inl +++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/StandardTetrahedralFEMForceField.inl @@ -268,7 +268,7 @@ void StandardTetrahedralFEMForceField::initNeighbourhoodEdges(){} template void StandardTetrahedralFEMForceField::addForce(const core::MechanicalParams* mparams , DataVecDeriv& d_f, const DataVecCoord& d_x, const DataVecDeriv& /* d_v */) { - helper::ScopedAdvancedTimer timer("addForceStandardTetraFEM"); + SCOPED_TIMER("addForceStandardTetraFEM"); VecDeriv& f = *d_f.beginEdit(); const VecCoord& x = d_x.getValue(); @@ -449,7 +449,7 @@ void StandardTetrahedralFEMForceField::addForce(const core::Mechanica template void StandardTetrahedralFEMForceField::addDForce(const core::MechanicalParams* mparams, DataVecDeriv& d_df, const DataVecDeriv& d_dx) { - helper::ScopedAdvancedTimer timer("addDForceStandardTetraFEM"); + SCOPED_TIMER("addDForceStandardTetraFEM"); VecDeriv& df = *d_df.beginEdit(); const VecDeriv& dx = d_dx.getValue(); diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialRestShapeSpringsForceField.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialRestShapeSpringsForceField.inl index f20be9c5d78d..63b75450260c 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialRestShapeSpringsForceField.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialRestShapeSpringsForceField.inl @@ -455,7 +455,7 @@ void PolynomialRestShapeSpringsForceField::addKToMatrix(const core::M { msg_info() << "[" << this->getName() << "]: addKToMatrix"; - helper::ScopedAdvancedTimer timer("restShapePolynomialSpringAddKToMatrix"); + SCOPED_TIMER("restShapePolynomialSpringAddKToMatrix"); const sofa::core::behavior::MultiMatrixAccessor::MatrixRef mref = matrix->getMatrix(this->mstate); sofa::linearalgebra::BaseMatrix* mat = mref.matrix; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.inl index 908521fef8b7..404401f90016 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.inl @@ -402,7 +402,7 @@ void PolynomialSpringsForceField::addKToMatrix(const core::Mechanical { msg_info() << "[" << this->getName() << "]: addKToMatrix"; - helper::ScopedAdvancedTimer timer("restShapeSpringAddKToMatrix"); + SCOPED_TIMER("restShapeSpringAddKToMatrix"); Real kFact = (Real)sofa::core::mechanicalparams::kFactorIncludingRayleighDamping(mparams, this->rayleighStiffness.getValue()); unsigned int firstIndex = 0; diff --git a/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TetrahedralTensorMassForceField.inl b/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TetrahedralTensorMassForceField.inl index 10d748675518..fafef56c5aae 100644 --- a/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TetrahedralTensorMassForceField.inl +++ b/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TetrahedralTensorMassForceField.inl @@ -342,7 +342,7 @@ void TetrahedralTensorMassForceField::initNeighbourhoodPoints() {} template SReal TetrahedralTensorMassForceField::getPotentialEnergy(const core::MechanicalParams* /* mparams */) const { - helper::ScopedAdvancedTimer timer("getPotentialEnergy"); + SCOPED_TIMER("getPotentialEnergy"); const VecCoord& x = this->mstate->read(core::ConstVecCoordId::position())->getValue(); @@ -381,7 +381,7 @@ SReal TetrahedralTensorMassForceField::getPotentialEnergy(const core template void TetrahedralTensorMassForceField::addForce(const core::MechanicalParams* /* mparams */, DataVecDeriv& d_f, const DataVecCoord& d_x, const DataVecDeriv& /* d_v */) { - helper::ScopedAdvancedTimer timer("addForceTetraTensorMass"); + SCOPED_TIMER("addForceTetraTensorMass"); VecDeriv& f = *d_f.beginEdit(); const VecCoord& x = d_x.getValue(); @@ -416,7 +416,7 @@ void TetrahedralTensorMassForceField::addForce(const core::Mechanical template void TetrahedralTensorMassForceField::addDForce(const core::MechanicalParams* mparams, DataVecDeriv& d_df, const DataVecDeriv& d_dx) { - helper::ScopedAdvancedTimer timer("addDForceTetraTensorMass"); + SCOPED_TIMER("addDForceTetraTensorMass"); VecDeriv& df = *d_df.beginEdit(); const VecDeriv& dx = d_dx.getValue(); diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyModifier.cpp b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyModifier.cpp index cd8f31c93c66..cf7b145525b4 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyModifier.cpp +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetTopologyModifier.cpp @@ -624,7 +624,7 @@ void EdgeSetTopologyModifier::splitEdgesProcess(sofa::type::vector &indi void EdgeSetTopologyModifier::removeEdges(const sofa::type::vector< EdgeID >& edgeIds, const bool removeIsolatedPoints) { - helper::ScopedAdvancedTimer removeEdgesTimer("removeEdges"); + SCOPED_TIMER_VARNAME(removeEdgesTimer, "removeEdges"); sofa::type::vector edgeIds_filtered; for (size_t i = 0; i < edgeIds.size(); i++) @@ -637,19 +637,19 @@ void EdgeSetTopologyModifier::removeEdges(const sofa::type::vector< EdgeID >& ed // add the topological changes in the queue { - helper::ScopedAdvancedTimer timer("removeEdgesWarning"); + SCOPED_TIMER("removeEdgesWarning"); removeEdgesWarning(edgeIds_filtered); } // inform other objects that the edges are going to be removed { - helper::ScopedAdvancedTimer timer("propagateTopologicalChanges"); + SCOPED_TIMER("propagateTopologicalChanges"); propagateTopologicalChanges(); } // now destroy the old edges. { - helper::ScopedAdvancedTimer timer("removeEdgesProcess"); + SCOPED_TIMER("removeEdgesProcess"); removeEdgesProcess( edgeIds_filtered, removeIsolatedPoints ); } @@ -663,14 +663,14 @@ void EdgeSetTopologyModifier::removeItems(const sofa::type::vector< EdgeID >& it void EdgeSetTopologyModifier::addEdges(const sofa::type::vector< Edge >& edges) { - helper::ScopedAdvancedTimer addEdgesTimer("addEdges"); + SCOPED_TIMER_VARNAME(addEdgesTimer, "addEdges"); const sofa::Size nEdges = m_container->getNumberOfEdges(); sofa::type::vector edgesIndex; // actually add edges in the topology container { - helper::ScopedAdvancedTimer addEdgesProcessTimer("addEdgesProcess"); + SCOPED_TIMER_VARNAME(addEdgesProcessTimer, "addEdgesProcess"); addEdgesProcess(edges); edgesIndex.reserve(edges.size()); @@ -682,13 +682,13 @@ void EdgeSetTopologyModifier::addEdges(const sofa::type::vector< Edge >& edges) // add topology event in the stack of topological events { - helper::ScopedAdvancedTimer addEdgesWarningTimer("addEdgesWarning"); + SCOPED_TIMER_VARNAME(addEdgesWarningTimer, "addEdgesWarning"); addEdgesWarning(sofa::Size(edges.size()), edges, edgesIndex); } // inform other objects that the edges are already added { - helper::ScopedAdvancedTimer timer("propagateTopologicalChanges"); + SCOPED_TIMER("propagateTopologicalChanges"); propagateTopologicalChanges(); } } @@ -697,14 +697,14 @@ void EdgeSetTopologyModifier::addEdges(const sofa::type::vector< Edge >& edges, const sofa::type::vector< sofa::type::vector< EdgeID > > & ancestors, const sofa::type::vector< sofa::type::vector< SReal > >& baryCoefs) { - helper::ScopedAdvancedTimer addEdgesTimer("addEdges with ancestors"); + SCOPED_TIMER_VARNAME(addEdgesTimer, "addEdges with ancestors"); const sofa::Index nEdges = m_container->getNumberOfEdges(); sofa::type::vector edgesIndex; /// actually add edges in the topology container { - helper::ScopedAdvancedTimer timer("propagateTopologicalChanges"); + SCOPED_TIMER("propagateTopologicalChanges"); addEdgesProcess(edges); edgesIndex.reserve(edges.size()); @@ -716,13 +716,13 @@ void EdgeSetTopologyModifier::addEdges(const sofa::type::vector< Edge >& edges, // add topology event in the stack of topological events { - helper::ScopedAdvancedTimer timer("addEdgesWarning"); + SCOPED_TIMER("addEdgesWarning"); addEdgesWarning(sofa::Size(edges.size()), edges, edgesIndex, ancestors, baryCoefs); } // inform other objects that the edges are already added { - helper::ScopedAdvancedTimer timer("propagateTopologicalChanges"); + SCOPED_TIMER("propagateTopologicalChanges"); propagateTopologicalChanges(); } } @@ -983,7 +983,7 @@ void EdgeSetTopologyModifier::propagateTopologicalEngineChanges() if (!m_container->isEdgeTopologyDirty()) // edge Data has not been touched return PointSetTopologyModifier::propagateTopologicalEngineChanges(); - helper::ScopedAdvancedTimer timer("EdgeSetTopologyModifier::propagateTopologicalEngineChanges"); + SCOPED_TIMER("EdgeSetTopologyModifier::propagateTopologicalEngineChanges"); auto& edgeTopologyHandlerList = m_container->getTopologyHandlerList(sofa::geometry::ElementType::EDGE); for (const auto topoHandler : edgeTopologyHandlerList) diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetTopologyModifier.cpp b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetTopologyModifier.cpp index 4b6d27d966e1..6573eb11f4be 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetTopologyModifier.cpp +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetTopologyModifier.cpp @@ -268,20 +268,20 @@ void PointSetTopologyModifier::addPointsWarning(const sofa::Size nPoints, void PointSetTopologyModifier::addPoints(const sofa::Size nPoints, const bool addDOF) { - helper::ScopedAdvancedTimer addPointsTimer("addPoints"); + SCOPED_TIMER_VARNAME(addPointsTimer, "addPoints"); { - helper::ScopedAdvancedTimer timer("addPointsProcess"); + SCOPED_TIMER("addPointsProcess"); addPointsProcess(nPoints); } { - helper::ScopedAdvancedTimer timer("addPointsWarning"); + SCOPED_TIMER("addPointsWarning"); addPointsWarning(nPoints, addDOF); } { - helper::ScopedAdvancedTimer timer("propagateTopologicalChanges"); + SCOPED_TIMER("propagateTopologicalChanges"); propagateTopologicalChanges(); } } @@ -291,20 +291,20 @@ void PointSetTopologyModifier::addPoints(const sofa::Size nPoints, const sofa::type::vector< sofa::type::vector< SReal> >& coefs, const bool addDOF) { - helper::ScopedAdvancedTimer addPointsTimer("addPoints with ancestors"); + SCOPED_TIMER_VARNAME(addPointsTimer, "addPoints with ancestors"); { - helper::ScopedAdvancedTimer timer("addPointsProcess"); + SCOPED_TIMER("addPointsProcess"); addPointsProcess(nPoints); } { - helper::ScopedAdvancedTimer timer("addPointsWarning"); + SCOPED_TIMER("addPointsWarning"); addPointsWarning(nPoints, ancestors, coefs, addDOF); } { - helper::ScopedAdvancedTimer timer("propagateTopologicalChanges"); + SCOPED_TIMER("propagateTopologicalChanges"); propagateTopologicalChanges(); } } @@ -346,20 +346,20 @@ void PointSetTopologyModifier::renumberPoints(const sofa::type::vector< PointID const sofa::type::vector< PointID >& inv_index, const bool renumberDOF) { - helper::ScopedAdvancedTimer renumberPointsTimer("Renumber Points"); + SCOPED_TIMER_VARNAME(renumberPointsTimer, "Renumber Points"); { - helper::ScopedAdvancedTimer timer("renumberPointsWarning"); + SCOPED_TIMER("renumberPointsWarning"); renumberPointsWarning(index, inv_index, renumberDOF); } { - helper::ScopedAdvancedTimer timer("propagateTopologicalChanges"); + SCOPED_TIMER("propagateTopologicalChanges"); propagateTopologicalChanges(); } { - helper::ScopedAdvancedTimer timer("renumberPointsProcess"); + SCOPED_TIMER("renumberPointsProcess"); renumberPointsProcess(index, inv_index, renumberDOF); } } @@ -367,20 +367,20 @@ void PointSetTopologyModifier::renumberPoints(const sofa::type::vector< PointID void PointSetTopologyModifier::removePoints(sofa::type::vector< PointID >& indices, const bool removeDOF) { - helper::ScopedAdvancedTimer removePointsTimer("Remove Points"); + SCOPED_TIMER_VARNAME(removePointsTimer, "Remove Points"); { - helper::ScopedAdvancedTimer timer("removePointsWarning"); + SCOPED_TIMER("removePointsWarning"); removePointsWarning(indices, removeDOF); } { - helper::ScopedAdvancedTimer timer("propagateTopologicalChanges"); + SCOPED_TIMER("propagateTopologicalChanges"); propagateTopologicalChanges(); } { - helper::ScopedAdvancedTimer timer("removePointsProcess"); + SCOPED_TIMER("removePointsProcess"); removePointsProcess(indices, removeDOF); } } @@ -390,7 +390,7 @@ void PointSetTopologyModifier::removePoints(sofa::type::vector< PointID >& indic void PointSetTopologyModifier::removePointsWarning(sofa::type::vector &indices, const bool removeDOF) { - helper::ScopedAdvancedTimer timer("removePointsWarning"); + SCOPED_TIMER("removePointsWarning"); m_container->setPointTopologyToDirty(); // sort points so that they are removed in a descending order @@ -411,7 +411,7 @@ void PointSetTopologyModifier::removePointsWarning(sofa::type::vector & void PointSetTopologyModifier::removePointsProcess(const sofa::type::vector & indices, const bool removeDOF) { - helper::ScopedAdvancedTimer timer("removePointsProcess"); + SCOPED_TIMER("removePointsProcess"); if(removeDOF) { propagateStateChanges(); @@ -472,7 +472,7 @@ void PointSetTopologyModifier::propagateTopologicalEngineChanges() if (!m_container->isPointTopologyDirty()) // triangle Data has not been touched return; - helper::ScopedAdvancedTimer timer("PointSetTopologyModifier::propagateTopologicalEngineChanges"); + SCOPED_TIMER("PointSetTopologyModifier::propagateTopologicalEngineChanges"); // get directly the list of engines created at init: case of removing.... for the moment auto& pointTopologyHandlerList = m_container->getTopologyHandlerList(sofa::geometry::ElementType::POINT); diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetTopologyModifier.cpp b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetTopologyModifier.cpp index b56fcd05314a..43d7a4204454 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetTopologyModifier.cpp +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetTopologyModifier.cpp @@ -616,19 +616,19 @@ void TetrahedronSetTopologyModifier::removeTetrahedra(const sofa::type::vector triangleIds_filtered; for (size_t i = 0; i < triangleIds.size(); i++) @@ -328,19 +328,19 @@ void TriangleSetTopologyModifier::removeTriangles(const sofa::type::vectorisTriangleTopologyDirty()) // triangle Data has not been touched return EdgeSetTopologyModifier::propagateTopologicalEngineChanges(); - helper::ScopedAdvancedTimer timer("TriangleSetTopologyModifier::propagateTopologicalEngineChanges"); + SCOPED_TIMER("TriangleSetTopologyModifier::propagateTopologicalEngineChanges"); auto& triangleTopologyHandlerList = m_container->getTopologyHandlerList(sofa::geometry::ElementType::TRIANGLE); for (const auto topoHandler : triangleTopologyHandlerList) diff --git a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Hexa2QuadTopologicalMapping.cpp b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Hexa2QuadTopologicalMapping.cpp index 324345c41b66..6129151606de 100644 --- a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Hexa2QuadTopologicalMapping.cpp +++ b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Hexa2QuadTopologicalMapping.cpp @@ -138,7 +138,7 @@ void Hexa2QuadTopologicalMapping::updateTopologicalMappingTopDown() if (this->d_componentState.getValue() != sofa::core::objectmodel::ComponentState::Valid) return; - helper::ScopedAdvancedTimer timer("Update Hexa2QuadTopologicalMapping"); + SCOPED_TIMER("Update Hexa2QuadTopologicalMapping"); container::dynamic::QuadSetTopologyModifier *to_tstm; toModel->getContext()->get(to_tstm); diff --git a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Quad2TriangleTopologicalMapping.cpp b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Quad2TriangleTopologicalMapping.cpp index 5a6f8a983ffd..1d949df31850 100644 --- a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Quad2TriangleTopologicalMapping.cpp +++ b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Quad2TriangleTopologicalMapping.cpp @@ -179,7 +179,7 @@ void Quad2TriangleTopologicalMapping::updateTopologicalMappingTopDown() if (this->d_componentState.getValue() != sofa::core::objectmodel::ComponentState::Valid) return; - helper::ScopedAdvancedTimer timer("Update Quad2TriangleTopologicalMapping"); + SCOPED_TIMER("Update Quad2TriangleTopologicalMapping"); TriangleSetTopologyModifier *to_tstm; toModel->getContext()->get(to_tstm); diff --git a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Tetra2TriangleTopologicalMapping.cpp b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Tetra2TriangleTopologicalMapping.cpp index 34b83ed8be41..7b648338e52e 100644 --- a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Tetra2TriangleTopologicalMapping.cpp +++ b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Tetra2TriangleTopologicalMapping.cpp @@ -148,7 +148,7 @@ void Tetra2TriangleTopologicalMapping::updateTopologicalMappingTopDown() if (this->d_componentState.getValue() != sofa::core::objectmodel::ComponentState::Valid) return; - helper::ScopedAdvancedTimer timer("Update Tetra2TriangleTopologicalMapping"); + SCOPED_TIMER("Update Tetra2TriangleTopologicalMapping"); auto itBegin=fromModel->beginChange(); auto itEnd=fromModel->endChange(); diff --git a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Triangle2EdgeTopologicalMapping.cpp b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Triangle2EdgeTopologicalMapping.cpp index 9eb4643700cc..a43dbf4e255e 100644 --- a/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Triangle2EdgeTopologicalMapping.cpp +++ b/Sofa/Component/Topology/Mapping/src/sofa/component/topology/mapping/Triangle2EdgeTopologicalMapping.cpp @@ -134,7 +134,7 @@ void Triangle2EdgeTopologicalMapping::updateTopologicalMappingTopDown() if (this->d_componentState.getValue() != sofa::core::objectmodel::ComponentState::Valid) return; - helper::ScopedAdvancedTimer timer("Update Triangle2EdgeTopologicalMapping"); + SCOPED_TIMER("Update Triangle2EdgeTopologicalMapping"); std::list::const_iterator itBegin=fromModel->beginChange(); std::list::const_iterator itEnd=fromModel->endChange(); diff --git a/Sofa/Component/Topology/Utility/src/sofa/component/topology/utility/TopologyBoundingTrasher.inl b/Sofa/Component/Topology/Utility/src/sofa/component/topology/utility/TopologyBoundingTrasher.inl index 8ba4676a3c16..0336a0391568 100644 --- a/Sofa/Component/Topology/Utility/src/sofa/component/topology/utility/TopologyBoundingTrasher.inl +++ b/Sofa/Component/Topology/Utility/src/sofa/component/topology/utility/TopologyBoundingTrasher.inl @@ -149,7 +149,7 @@ void TopologyBoundingTrasher::reinit() template void TopologyBoundingTrasher::filterElementsToRemove() { - helper::ScopedAdvancedTimer timer("filterElementsToRemove"); + SCOPED_TIMER("filterElementsToRemove"); const VecCoord& positions = d_positions.getValue(); const Vec6& border = d_borders.getValue(); diff --git a/Sofa/Component/Visual/src/sofa/component/visual/VisualModelImpl.cpp b/Sofa/Component/Visual/src/sofa/component/visual/VisualModelImpl.cpp index 5a28631a7bda..d7b412c5246d 100644 --- a/Sofa/Component/Visual/src/sofa/component/visual/VisualModelImpl.cpp +++ b/Sofa/Component/Visual/src/sofa/component/visual/VisualModelImpl.cpp @@ -1317,25 +1317,25 @@ void VisualModelImpl::updateVisual() } { - sofa::helper::ScopedAdvancedTimer t("VisualModelImpl::computePositions"); + SCOPED_TIMER_VARNAME(t, "VisualModelImpl::computePositions"); computePositions(); } { - sofa::helper::ScopedAdvancedTimer t("VisualModelImpl::computeNormals"); + SCOPED_TIMER_VARNAME(t, "VisualModelImpl::computeNormals"); computeNormals(); } if (m_updateTangents.getValue()) { - sofa::helper::ScopedAdvancedTimer t("VisualModelImpl::computeTangents"); + SCOPED_TIMER_VARNAME(t, "VisualModelImpl::computeTangents"); computeTangents(); } if (m_vtexcoords.getValue().size() == 0) { - sofa::helper::ScopedAdvancedTimer t("VisualModelImpl::computeUVSphereProjection"); + SCOPED_TIMER_VARNAME(t, "VisualModelImpl::computeUVSphereProjection"); computeUVSphereProjection(); } { - sofa::helper::ScopedAdvancedTimer t("VisualModelImpl::updateBuffers"); + SCOPED_TIMER_VARNAME(t, "VisualModelImpl::updateBuffers"); updateBuffers(); } diff --git a/Sofa/GUI/Common/src/sofa/gui/common/BaseGUI.cpp b/Sofa/GUI/Common/src/sofa/gui/common/BaseGUI.cpp index 7cb2aa093090..90b87cf34ace 100644 --- a/Sofa/GUI/Common/src/sofa/gui/common/BaseGUI.cpp +++ b/Sofa/GUI/Common/src/sofa/gui/common/BaseGUI.cpp @@ -116,7 +116,7 @@ void BaseGUI::configureGUI(sofa::simulation::Node::SPtr groot) void BaseGUI::exportGnuplot(sofa::simulation::Node* node, std::string /*gnuplot_directory*/ ) { - sofa::helper::ScopedAdvancedTimer exportGnuplotTimer("exportGnuplot"); + SCOPED_TIMER_VARNAME(exportGnuplotTimer, "exportGnuplot"); const sofa::core::ExecParams* params = sofa::core::execparams::defaultInstance(); ExportGnuplotVisitor expg ( params, node->getTime()); diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/RealGUI.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/RealGUI.cpp index 4d24778a7420..442d20d86eae 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/RealGUI.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/RealGUI.cpp @@ -2128,7 +2128,7 @@ void RealGUI::exportOBJ (simulation::Node* root, bool exportMTL ) { if ( !root ) return; - sofa::helper::ScopedAdvancedTimer exportOBJTimer("exportOBJ"); + SCOPED_TIMER_VARNAME(exportOBJTimer, "exportOBJ"); const std::string sceneFileName(this->windowFilePath ().toStdString()); std::ostringstream ofilename; diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/CollisionAnimationLoop.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/CollisionAnimationLoop.cpp index 267bc39e74e5..8e1ccf6899c7 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/CollisionAnimationLoop.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/CollisionAnimationLoop.cpp @@ -55,7 +55,7 @@ CollisionAnimationLoop::~CollisionAnimationLoop() void CollisionAnimationLoop::preCollisionComputation(const core::ExecParams *params) { - sofa::helper::ScopedAdvancedTimer timer("CollisionBeginEvent"); + SCOPED_TIMER("CollisionBeginEvent"); CollisionBeginEvent evBegin; PropagateEventVisitor eventPropagation( params, &evBegin); eventPropagation.execute(getContext()); @@ -63,7 +63,7 @@ void CollisionAnimationLoop::preCollisionComputation(const core::ExecParams *par void CollisionAnimationLoop::internalCollisionComputation(const core::ExecParams *params) { - sofa::helper::ScopedAdvancedTimer timer("CollisionVisitor"); + SCOPED_TIMER("CollisionVisitor"); CollisionVisitor act(params); act.setTags(this->getTags()); act.execute(getContext()); @@ -71,7 +71,7 @@ void CollisionAnimationLoop::internalCollisionComputation(const core::ExecParams void CollisionAnimationLoop::postCollisionComputation(const core::ExecParams *params) { - sofa::helper::ScopedAdvancedTimer timer("CollisionEndEvent"); + SCOPED_TIMER("CollisionEndEvent"); CollisionEndEvent evEnd; PropagateEventVisitor eventPropagation( params, &evEnd); eventPropagation.execute(getContext()); diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp index f63c645738c4..1673a6940d91 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp @@ -117,20 +117,20 @@ void DefaultAnimationLoop::setNode(simulation::Node* n) void DefaultAnimationLoop::behaviorUpdatePosition(const core::ExecParams* params, const SReal dt) const { - sofa::helper::ScopedAdvancedTimer timer("BehaviorUpdatePositionVisitor"); + SCOPED_TIMER("BehaviorUpdatePositionVisitor"); BehaviorUpdatePositionVisitor beh(params, dt); m_node->execute(beh); } void DefaultAnimationLoop::updateInternalData(const core::ExecParams* params) const { - sofa::helper::ScopedAdvancedTimer timer("UpdateInternalDataVisitor"); + SCOPED_TIMER("UpdateInternalDataVisitor"); m_node->execute(params); } void DefaultAnimationLoop::updateSimulationContext(const core::ExecParams* params, const SReal dt, const SReal startTime) const { - sofa::helper::ScopedAdvancedTimer timer("UpdateSimulationContextVisitor"); + SCOPED_TIMER("UpdateSimulationContextVisitor"); m_node->setTime(startTime + dt); m_node->execute(params); } @@ -144,7 +144,7 @@ void DefaultAnimationLoop::propagateAnimateEndEvent(const core::ExecParams* para void DefaultAnimationLoop::updateMapping(const core::ExecParams* params, const SReal dt) const { - sofa::helper::ScopedAdvancedTimer timer("UpdateMapping"); + SCOPED_TIMER("UpdateMapping"); //Visual Information update: Ray Pick add a MechanicalMapping used as VisualMapping m_node->execute(params); { @@ -158,7 +158,7 @@ void DefaultAnimationLoop::computeBoundingBox(const core::ExecParams* params) co { if (d_computeBoundingBox.getValue()) { - sofa::helper::ScopedAdvancedTimer timer("UpdateBBox"); + SCOPED_TIMER("UpdateBBox"); m_node->execute(params); } } @@ -172,7 +172,7 @@ void DefaultAnimationLoop::propagateAnimateBeginEvent(const core::ExecParams* pa void DefaultAnimationLoop::resetConstraint(const core::ExecParams* params) const { - sofa::helper::ScopedAdvancedTimer timer("resetConstraint"); + SCOPED_TIMER("resetConstraint"); const sofa::core::ConstraintParams cparams(*params); sofa::simulation::mechanicalvisitor::MechanicalResetConstraintVisitor resetConstraint(&cparams); m_node->execute(&resetConstraint); @@ -182,14 +182,14 @@ void DefaultAnimationLoop::beginIntegration(const core::ExecParams* params, SRea { propagateIntegrateBeginEvent(params); - sofa::helper::ScopedAdvancedTimer timer("beginIntegration"); + SCOPED_TIMER("beginIntegration"); mechanicalvisitor::MechanicalBeginIntegrationVisitor beginVisitor(params, dt); m_node->execute(&beginVisitor); } void DefaultAnimationLoop::propagateIntegrateBeginEvent(const core::ExecParams* params) const { - sofa::helper::ScopedAdvancedTimer timer("propagateIntegrateBeginEvent"); + SCOPED_TIMER("propagateIntegrateBeginEvent"); IntegrateBeginEvent evBegin; PropagateEventVisitor eventPropagation( params, &evBegin); eventPropagation.execute(m_node); @@ -197,7 +197,7 @@ void DefaultAnimationLoop::propagateIntegrateBeginEvent(const core::ExecParams* void DefaultAnimationLoop::buildConstraintMatrix(core::ConstraintParams cparams) const { - sofa::helper::ScopedAdvancedTimer timer("buildConstraintMatrix"); + SCOPED_TIMER("buildConstraintMatrix"); unsigned int constraintId = 0; mechanicalvisitor::MechanicalBuildConstraintMatrix buildConstraintMatrix(&cparams, core::MatrixDerivId::constraintJacobian(), constraintId ); buildConstraintMatrix.execute(m_node); @@ -205,7 +205,7 @@ void DefaultAnimationLoop::buildConstraintMatrix(core::ConstraintParams cparams) void DefaultAnimationLoop::accumulateMatrixDeriv(const core::ConstraintParams cparams) const { - sofa::helper::ScopedAdvancedTimer timer("accumulateMatrixDeriv"); + SCOPED_TIMER("accumulateMatrixDeriv"); mechanicalvisitor::MechanicalAccumulateMatrixDeriv accumulateMatrixDeriv(&cparams, core::MatrixDerivId::constraintJacobian()); accumulateMatrixDeriv.execute(m_node); } @@ -214,14 +214,14 @@ void DefaultAnimationLoop::solve(const core::ExecParams* params, SReal dt) const { constexpr bool usefreeVecIds = false; constexpr bool computeForceIsolatedInteractionForceFields = true; - sofa::helper::ScopedAdvancedTimer timer("solve"); + SCOPED_TIMER("solve"); simulation::SolveVisitor freeMotion(params, dt, usefreeVecIds, d_parallelODESolving.getValue(), computeForceIsolatedInteractionForceFields); freeMotion.execute(m_node); } void DefaultAnimationLoop::propagateIntegrateEndEvent(const core::ExecParams* params) const { - sofa::helper::ScopedAdvancedTimer timer("propagateIntegrateEndEvent"); + SCOPED_TIMER("propagateIntegrateEndEvent"); IntegrateEndEvent evBegin; PropagateEventVisitor eventPropagation(params, &evBegin); eventPropagation.execute(m_node); @@ -230,7 +230,7 @@ void DefaultAnimationLoop::propagateIntegrateEndEvent(const core::ExecParams* pa void DefaultAnimationLoop::endIntegration(const core::ExecParams* params, const SReal dt) const { { - sofa::helper::ScopedAdvancedTimer timer("endIntegration"); + SCOPED_TIMER("endIntegration"); mechanicalvisitor::MechanicalEndIntegrationVisitor endVisitor(params, dt); m_node->execute(&endVisitor); } @@ -240,7 +240,7 @@ void DefaultAnimationLoop::endIntegration(const core::ExecParams* params, const void DefaultAnimationLoop::projectPositionAndVelocity(const SReal nextTime, const sofa::core::MechanicalParams& mparams) const { - sofa::helper::ScopedAdvancedTimer timer("projectPositionAndVelocity"); + SCOPED_TIMER("projectPositionAndVelocity"); mechanicalvisitor::MechanicalProjectPositionAndVelocityVisitor(&mparams, nextTime, sofa::core::VecCoordId::position(), sofa::core::VecDerivId::velocity() ).execute( m_node ); @@ -248,7 +248,7 @@ void DefaultAnimationLoop::projectPositionAndVelocity(const SReal nextTime, cons void DefaultAnimationLoop::propagateOnlyPositionAndVelocity(const SReal nextTime, const sofa::core::MechanicalParams& mparams) const { - sofa::helper::ScopedAdvancedTimer timer("propagateOnlyPositionAndVelocity"); + SCOPED_TIMER("propagateOnlyPositionAndVelocity"); mechanicalvisitor::MechanicalPropagateOnlyPositionAndVelocityVisitor(&mparams, nextTime, core::VecCoordId::position(), core::VecDerivId::velocity()).execute( m_node ); @@ -273,7 +273,7 @@ void DefaultAnimationLoop::collisionDetection(const core::ExecParams* params) co propagateCollisionBeginEvent(params); { - sofa::helper::ScopedAdvancedTimer timer("collision"); + SCOPED_TIMER("collision"); CollisionVisitor act(params); m_node->execute(&act); } diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/PipelineImpl.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/PipelineImpl.cpp index 6abe0cb6a96b..1d201c1d16c5 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/PipelineImpl.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/PipelineImpl.cpp @@ -106,7 +106,7 @@ void PipelineImpl::computeCollisionReset() if (contactManager!=nullptr && contactManager->getIntersectionMethod()!=intersectionMethod) contactManager->setIntersectionMethod(intersectionMethod); - helper::ScopedAdvancedTimer timer("CollisionReset"); + SCOPED_TIMER("CollisionReset"); doCollisionReset(); } @@ -124,7 +124,7 @@ void PipelineImpl::computeCollisionResponse() const simulation::Node* root = dynamic_cast(getContext()); if(root == nullptr) return; - helper::ScopedAdvancedTimer timer("CollisionResponse"); + SCOPED_TIMER("CollisionResponse"); doCollisionResponse(); } diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/Simulation.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/Simulation.cpp index 7a69f480f207..9dbb0bf8e277 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/Simulation.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/Simulation.cpp @@ -81,7 +81,7 @@ namespace node void initRoot(Node* root) { - sofa::helper::ScopedAdvancedTimer timer("Simulation::init"); + SCOPED_TIMER("Simulation::init"); if (!root) { return; @@ -207,7 +207,7 @@ void updateVisualContext(Node* root) void animate(Node* root, SReal dt) { - sofa::helper::ScopedAdvancedTimer timer("Simulation::animate"); + SCOPED_TIMER("Simulation::animate"); if (!root) { @@ -229,7 +229,7 @@ void animate(Node* root, SReal dt) void updateVisual(Node* root) { - sofa::helper::ScopedAdvancedTimer timer("Simulation::updateVisual"); + SCOPED_TIMER("Simulation::updateVisual"); sofa::core::ExecParams* params = sofa::core::execparams::defaultInstance(); @@ -338,7 +338,7 @@ void computeTotalBBox(Node* root, SReal* minBBox, SReal* maxBBox) void draw(sofa::core::visual::VisualParams* vparams, Node* root) { - sofa::helper::ScopedAdvancedTimer timer("Simulation::draw"); + SCOPED_TIMER("Simulation::draw"); for (const auto& visualLoop : root->getTreeObjects()) { @@ -412,7 +412,7 @@ void exportGraph(Node* root, const char* filename) void dumpState(Node* root, std::ofstream& out) { - sofa::helper::ScopedAdvancedTimer dumpStateTimer("dumpState"); + SCOPED_TIMER_VARNAME(dumpStateTimer, "dumpState"); const sofa::core::ExecParams* params = sofa::core::execparams::defaultInstance(); out << root->getTime() << " "; diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/SolveVisitor.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/SolveVisitor.cpp index 1f74b846d016..2d57a4496102 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/SolveVisitor.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/SolveVisitor.cpp @@ -81,7 +81,7 @@ void SolveVisitor::processNodeBottomUp(simulation::Node*) { auto* taskScheduler = sofa::simulation::MainTaskSchedulerFactory::createInRegistry(); assert(taskScheduler != nullptr); - sofa::helper::ScopedAdvancedTimer parallelSolveTimer("waitParallelTasks"); + SCOPED_TIMER_VARNAME(parallelSolveTimer, "waitParallelTasks"); taskScheduler->workUntilDone(&m_status); } m_tasks.clear(); diff --git a/applications/collections/deprecated/modules/SofaMiscCollision/src/SofaMiscCollision/DefaultCollisionGroupManager.cpp b/applications/collections/deprecated/modules/SofaMiscCollision/src/SofaMiscCollision/DefaultCollisionGroupManager.cpp index 5c3798b1a730..0e393f0821f2 100644 --- a/applications/collections/deprecated/modules/SofaMiscCollision/src/SofaMiscCollision/DefaultCollisionGroupManager.cpp +++ b/applications/collections/deprecated/modules/SofaMiscCollision/src/SofaMiscCollision/DefaultCollisionGroupManager.cpp @@ -68,7 +68,7 @@ void DefaultCollisionGroupManager::changeInstance(Instance inst) void DefaultCollisionGroupManager::createGroups(core::objectmodel::BaseContext* scene, const sofa::type::vector& contacts) { - sofa::helper::ScopedAdvancedTimer timer("CreateGroups"); + SCOPED_TIMER("CreateGroups"); int groupIndex = 1; diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/solidmechanics/fem/hyperelastic/CudaStandardTetrahedralFEMForceField.inl b/applications/plugins/SofaCUDA/src/SofaCUDA/component/solidmechanics/fem/hyperelastic/CudaStandardTetrahedralFEMForceField.inl index ebaf17e44162..933fae9496a5 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/solidmechanics/fem/hyperelastic/CudaStandardTetrahedralFEMForceField.inl +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/solidmechanics/fem/hyperelastic/CudaStandardTetrahedralFEMForceField.inl @@ -50,7 +50,7 @@ using namespace gpu::cuda; template <> void StandardTetrahedralFEMForceField::addForce(const core::MechanicalParams* /*mparams*/, DataVecDeriv& d_f, const DataVecCoord& d_x, const DataVecDeriv& /*d_v*/) { - helper::ScopedAdvancedTimer timer("addForceStandardTetraFEM"); + SCOPED_TIMER("addForceStandardTetraFEM"); VecDeriv& f = *d_f.beginEdit(); const VecCoord& x = d_x.getValue(); @@ -86,7 +86,7 @@ void StandardTetrahedralFEMForceField::addForce(const template <> void StandardTetrahedralFEMForceField::addDForce(const core::MechanicalParams* mparams, DataVecDeriv& d_df, const DataVecDeriv& d_dx) { - helper::ScopedAdvancedTimer timer("addDForceStandardTetraFEM"); + SCOPED_TIMER("addDForceStandardTetraFEM"); VecDeriv& df = *d_df.beginEdit(); const VecDeriv& dx = d_dx.getValue(); diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/solidmechanics/tensormass/CudaTetrahedralTensorMassForceField.inl b/applications/plugins/SofaCUDA/src/SofaCUDA/component/solidmechanics/tensormass/CudaTetrahedralTensorMassForceField.inl index 9861cc05e368..7ef115c3109e 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/solidmechanics/tensormass/CudaTetrahedralTensorMassForceField.inl +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/solidmechanics/tensormass/CudaTetrahedralTensorMassForceField.inl @@ -52,7 +52,7 @@ using namespace gpu::cuda; template <> void TetrahedralTensorMassForceField::addForce(const core::MechanicalParams* /*mparams*/, DataVecDeriv& d_f, const DataVecCoord& d_x, const DataVecDeriv& /*d_v*/) { - helper::ScopedAdvancedTimer timer("addForceTetraTensorMass"); + SCOPED_TIMER("addForceTetraTensorMass"); VecDeriv& f = *d_f.beginEdit(); const VecCoord& x = d_x.getValue(); @@ -72,7 +72,7 @@ using namespace gpu::cuda; template <> void TetrahedralTensorMassForceField::addDForce(const core::MechanicalParams* mparams, DataVecDeriv& d_df, const DataVecDeriv& d_dx) { - helper::ScopedAdvancedTimer timer("addDForceTetraTensorMass"); + SCOPED_TIMER("addDForceTetraTensorMass"); VecDeriv& df = *d_df.beginEdit(); const VecDeriv& dx = d_dx.getValue(); diff --git a/applications/plugins/SofaCarving/src/SofaCarving/CarvingManager.cpp b/applications/plugins/SofaCarving/src/SofaCarving/CarvingManager.cpp index 9eb731fe3796..7badf398cef8 100644 --- a/applications/plugins/SofaCarving/src/SofaCarving/CarvingManager.cpp +++ b/applications/plugins/SofaCarving/src/SofaCarving/CarvingManager.cpp @@ -121,7 +121,7 @@ void CarvingManager::doCarve() if (detectionOutputs.size() == 0) return; - sofa::helper::ScopedAdvancedTimer timer("CarvingElems"); + SCOPED_TIMER("CarvingElems"); // loop on the contact to get the one between the CarvingSurface and the CarvingTool collision model const SReal& carvDist = d_carvingDistance.getValue(); From d749cc5858c3840eef3ee3f6ec7b2aef76658395 Mon Sep 17 00:00:00 2001 From: Hugo Date: Thu, 28 Sep 2023 10:13:30 +0200 Subject: [PATCH 02/60] [examples] Fix warning of UncoupledCC in caduceus (#4187) [examples] Fix warning in caduceus --- examples/Demos/caduceus.scn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Demos/caduceus.scn b/examples/Demos/caduceus.scn index be820beeac59..16e49cdb5dd8 100644 --- a/examples/Demos/caduceus.scn +++ b/examples/Demos/caduceus.scn @@ -52,7 +52,7 @@ - + From ddec7adcfc860c14a372b658772ad16e65aea1ed Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 4 Oct 2023 14:34:26 +0200 Subject: [PATCH 03/60] [Core] Store default value in a Data (#4133) * Replace all ScopedAdvancedTimer timers by macro * use SCOPED_TIMER_VARNAME for timers with a variable name * [Core] Store default value in a Data * Show default value of a Data in its description * Fix compilation of MyData * Remove template selection --- .../Qt/src/sofa/gui/qt/QDisplayDataWidget.cpp | 6 ++++++ .../Core/src/sofa/core/objectmodel/BaseData.h | 3 +++ .../Core/src/sofa/core/objectmodel/Data.h | 18 +++++++++++++++++- .../Core/test/objectmodel/BaseData_test.cpp | 1 + 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/QDisplayDataWidget.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/QDisplayDataWidget.cpp index 7e0ee0cd3577..f34018ffb5ee 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/QDisplayDataWidget.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/QDisplayDataWidget.cpp @@ -62,12 +62,18 @@ QDisplayDataWidget::QDisplayDataWidget(QWidget* parent, const std::string& help = data_->getHelp().c_str(); const std::string valuetype = data_->getValueTypeString(); const std::string& ownerClass = data_->getOwner()->getClassName(); + const std::string defaultValue = data_->getDefaultValueString(); std::stringstream s; s << (!help.empty() ? help : "< No help found >") << "\nData type: " << valuetype << "\nOwner: " << (!ownerClass.empty() ? ownerClass : "< No owner found >"); + if (!defaultValue.empty()) + { + s << "\nDefault value: " << defaultValue; + } + const std::string fullHelpText = s.str(); setToolTip(fullHelpText.c_str()); datainfowidget_ = new QDisplayDataInfoWidget(this,fullHelpText,data_, diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.h b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.h index 73aa81a9184d..aaef1b3abe32 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.h +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/BaseData.h @@ -112,6 +112,9 @@ class SOFA_CORE_API BaseData : public DDGNode /// Get a string representation of the value held in this %Data. virtual std::string getValueString() const = 0; + /// Get a string representation of the default value held in this %Data. + virtual std::string getDefaultValueString() const = 0; + /// Get the name of the type of the value held in this %Data. virtual std::string getValueTypeString() const = 0; diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/Data.h b/Sofa/framework/Core/src/sofa/core/objectmodel/Data.h index 192f98419685..8d9ec2dac6d0 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/Data.h +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/Data.h @@ -111,6 +111,7 @@ class Data : public BaseData { m_value = ValueType(init.value); m_hasDefaultValue = true; + m_defaultValue = init.value; } /** \copydoc BaseData(const char*, bool, bool) */ @@ -200,6 +201,7 @@ class Data : public BaseData bool read( const std::string& s ) override; void printValue(std::ostream& out) const override; std::string getValueString() const override; + std::string getDefaultValueString() const override; std::string getValueTypeString() const override; void operator =( const T& value ) @@ -216,6 +218,7 @@ class Data : public BaseData protected: typedef DataContentValue> ValueType; + T m_defaultValue; /// Value ValueType m_value; @@ -259,7 +262,7 @@ void Data::printValue( std::ostream& out) const out << getValue() << " "; } -/// General case for printing default value +/// General case for printing value template std::string Data::getValueString() const { @@ -268,6 +271,19 @@ std::string Data::getValueString() const return out.str(); } +/// General case for printing default value +template +std::string Data::getDefaultValueString() const +{ + if (hasDefaultValue()) + { + std::ostringstream out; + out << this->m_defaultValue; + return out.str(); + } + return {}; +} + template std::string Data::getValueTypeString() const { diff --git a/Sofa/framework/Core/test/objectmodel/BaseData_test.cpp b/Sofa/framework/Core/test/objectmodel/BaseData_test.cpp index 31f03944f1dc..2cd808fbc9b5 100644 --- a/Sofa/framework/Core/test/objectmodel/BaseData_test.cpp +++ b/Sofa/framework/Core/test/objectmodel/BaseData_test.cpp @@ -35,6 +35,7 @@ class MyData : public BaseData bool read(const std::string&)override {return true;} void printValue(std::ostream&) const override {return;} std::string getValueString() const override {return "";} + std::string getDefaultValueString() const override { return ""; } std::string getValueTypeString() const override {return "";} const sofa::defaulttype::AbstractTypeInfo* getValueTypeInfo() const override {return nullptr;} const void* getValueVoidPtr() const {return nullptr;} From 6ad8a3a2e40b0c17d62d4a6d533f07c67d647836 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Wed, 4 Oct 2023 21:37:39 +0900 Subject: [PATCH 04/60] [Constraint.Lagrangian.Solver] GenericConstraintSolver: avoid repeated allocation in loops (#4195) * use allocated array to old temp data * just resize the temp vectors if needed --- .../solver/GenericConstraintProblem.cpp | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintProblem.cpp b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintProblem.cpp index 04384614b014..7f80cccce130 100644 --- a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintProblem.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintProblem.cpp @@ -269,7 +269,7 @@ void GenericConstraintProblem::unbuiltGaussSeidel(SReal timeout, GenericConstrai SReal *d = _d.ptr(); - int iter, nb; + unsigned int iter = 0, nb = 0; SReal error=0.0; @@ -317,7 +317,11 @@ void GenericConstraintProblem::unbuiltGaussSeidel(SReal timeout, GenericConstrai tabErrors.resize(dimension); - for(iter=0; iter errF; + std::vector tempF; + + for(iter=0; iter < static_cast(maxIterations); iter++) { bool constraintsAreVerified = true; if(sor != 1.0) @@ -334,7 +338,11 @@ void GenericConstraintProblem::unbuiltGaussSeidel(SReal timeout, GenericConstrai //2. for each line we compute the actual value of d // (a)d is set to dfree - std::vector errF(&force[j], &force[j+nb]); + if(nb > errF.size()) + { + errF.resize(nb); + } + std::copy_n(&force[j], nb, errF.begin()); std::copy_n(&dfree[j], nb, &d[j]); // (b) contribution of forces are added to d @@ -351,10 +359,10 @@ void GenericConstraintProblem::unbuiltGaussSeidel(SReal timeout, GenericConstrai SReal contraintError = 0.0; if(nb > 1) { - for(int l=0; l tempF (&force[j], &force[j+nb]); - for(int l=0; l tempF.size()) + { + tempF.resize(nb); + } + std::copy_n(&force[j], nb, tempF.begin()); + for(unsigned int l=0; lsetConstraintDForce(force, j, j+nb-1, update); } - std::copy(tempF.begin(), tempF.end(), &force[j]); - } + std::copy_n(tempF.begin(), nb, &force[j]); + } std::advance(it_c, nb); } From 77278d68580aff7bcb8e27daad9bc34e6755daa7 Mon Sep 17 00:00:00 2001 From: erik pernod Date: Wed, 4 Oct 2023 14:39:06 +0200 Subject: [PATCH 05/60] [Topology.Container] Remove method writeMSHfile in GeometryAlgorithms components (#4192) --- .../dynamic/EdgeSetGeometryAlgorithms.h | 3 +- .../dynamic/EdgeSetGeometryAlgorithms.inl | 39 ----------------- .../dynamic/HexahedronSetGeometryAlgorithms.h | 7 ++-- .../HexahedronSetGeometryAlgorithms.inl | 42 ------------------- .../dynamic/QuadSetGeometryAlgorithms.h | 7 ++-- .../dynamic/QuadSetGeometryAlgorithms.inl | 39 ----------------- .../TetrahedronSetGeometryAlgorithms.h | 6 +-- .../TetrahedronSetGeometryAlgorithms.inl | 42 ------------------- .../dynamic/TriangleSetGeometryAlgorithms.h | 7 +--- .../dynamic/TriangleSetGeometryAlgorithms.inl | 40 ------------------ 10 files changed, 13 insertions(+), 219 deletions(-) diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h index e946d3bdaea9..46a3520af440 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h @@ -134,7 +134,6 @@ class EdgeSetGeometryAlgorithms : public PointSetGeometryAlgorithms bool computeEdgePlaneIntersection (EdgeID edgeID, sofa::type::Vec<3,Real> pointOnPlane, sofa::type::Vec<3,Real> normalOfPlane, sofa::type::Vec<3,Real>& intersection); bool computeRestEdgePlaneIntersection (EdgeID edgeID, sofa::type::Vec<3,Real> pointOnPlane, sofa::type::Vec<3,Real> normalOfPlane, sofa::type::Vec<3,Real>& intersection); - void writeMSHfile(const char *filename) const; /** Computes weights allowing to compute the deformation gradient (deformed basis) at each vertex during the simulation, for a volumetric object. For each vertex, computes the weights associated with each edge around the vertex, so that the weighted sum of the edges corresponds to the identity. @@ -162,6 +161,8 @@ class EdgeSetGeometryAlgorithms : public PointSetGeometryAlgorithms const sofa::type::Vec<3, Real>& b, Real &baryCoef); + SOFA_ATTRIBUTE_DISABLED("v23.12", "v23.12", "Method writeMSHfile has been disabled. To export the topology as .gmsh file, use the sofa::component::io::mesh::MeshExporter.") + void writeMSHfile(const char *filename) const {msg_deprecated() << "Method writeMSHfile has been disabled. To export the topology as " << filename << " file, use the sofa::component::io::mesh::MeshExporter."; } protected: Data showEdgeIndices; ///< Debug : view Edge indices. Data d_drawEdges; ///< if true, draw the edges in the topology. diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.inl b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.inl index db03da9dc168..5b2f8369e253 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.inl +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.inl @@ -402,45 +402,6 @@ auto EdgeSetGeometryAlgorithms::compute2PointsBarycoefs( } -/// Write the current mesh into a msh file -template -void EdgeSetGeometryAlgorithms::writeMSHfile(const char *filename) const -{ - std::ofstream myfile; - myfile.open (filename); - - const typename DataTypes::VecCoord& vect_c =(this->object->read(core::ConstVecCoordId::position())->getValue()); - - const size_t numVertices = vect_c.size(); - - myfile << "$NOD\n"; - myfile << numVertices <<"\n"; - - for (size_t i=0; i &edge = this->m_topology->getEdges(); - - myfile << edge.size() <<"\n"; - - for (size_t i=0; i bool is_point_on_edge(const Vec& p, const Vec& a, const Vec& b) { diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetGeometryAlgorithms.h index e1f5261c60f8..c81951f7c5e8 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetGeometryAlgorithms.h @@ -145,12 +145,11 @@ class HexahedronSetGeometryAlgorithms : public QuadSetGeometryAlgorithms &getHexahedronNumericalIntegrationDescriptor(); - /** \brief Write the current mesh into a msh file - */ - void writeMSHfile(const char *filename) const; - void draw(const core::visual::VisualParams* vparams) override; + SOFA_ATTRIBUTE_DISABLED("v23.12", "v23.12", "Method writeMSHfile has been disabled. To export the topology as .gmsh file, use the sofa::component::io::mesh::MeshExporter.") + void writeMSHfile(const char *filename) const {msg_deprecated() << "Method writeMSHfile has been disabled. To export the topology as " << filename << " file, use the sofa::component::io::mesh::MeshExporter."; } + protected: Data d_showHexaIndices; ///< Debug : view Hexa indices Data d_drawHexahedra; ///< if true, draw the Hexahedron in the topology diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetGeometryAlgorithms.inl b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetGeometryAlgorithms.inl index 81212cfc864b..2034fe241bc2 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetGeometryAlgorithms.inl +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetGeometryAlgorithms.inl @@ -781,48 +781,6 @@ void HexahedronSetGeometryAlgorithms::computeHexahedronVolume( BasicA } } -/// Write the current mesh into a msh file -template -void HexahedronSetGeometryAlgorithms::writeMSHfile(const char *filename) const -{ - std::ofstream myfile; - myfile.open (filename); - - const typename DataTypes::VecCoord& vect_c =(this->object->read(core::ConstVecCoordId::position())->getValue()); - - const size_t numVertices = vect_c.size(); - - myfile << "$NOD\n"; - myfile << numVertices <<"\n"; - - for(size_t i=0; i& hea = this->m_topology->getHexahedra(); - - myfile << hea.size() <<"\n"; - - for(size_t i=0; i void HexahedronSetGeometryAlgorithms::draw(const core::visual::VisualParams* vparams) diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetGeometryAlgorithms.h index 591c301a5360..1e6c4b2bb096 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetGeometryAlgorithms.h @@ -99,12 +99,11 @@ class QuadSetGeometryAlgorithms : public EdgeSetGeometryAlgorithms bool isPointInQuad(const QuadID ind_q, const sofa::type::Vec<3,Real>& p) const; - /** \brief Write the current mesh into a msh file - */ - void writeMSHfile(const char *filename) const; - void draw(const core::visual::VisualParams* vparams) override; + SOFA_ATTRIBUTE_DISABLED("v23.12", "v23.12", "Method writeMSHfile has been disabled. To export the topology as .gmsh file, use the sofa::component::io::mesh::MeshExporter.") + void writeMSHfile(const char *filename) const {msg_deprecated() << "Method writeMSHfile has been disabled. To export the topology as " << filename << " file, use the sofa::component::io::mesh::MeshExporter."; } + protected: Data showQuadIndices; ///< Debug : view Quad indices Data _drawQuads; ///< if true, draw the quads in the topology diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetGeometryAlgorithms.inl b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetGeometryAlgorithms.inl index b8d53b95b00c..e131a626bbb0 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetGeometryAlgorithms.inl +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetGeometryAlgorithms.inl @@ -246,45 +246,6 @@ bool QuadSetGeometryAlgorithms< DataTypes >::isPointInQuad(const QuadID ind_q, c return false; } -/// Write the current mesh into a msh file -template -void QuadSetGeometryAlgorithms::writeMSHfile(const char *filename) const -{ - std::ofstream myfile; - myfile.open (filename); - - const typename DataTypes::VecCoord& vect_c =(this->object->read(core::ConstVecCoordId::position())->getValue()); - - const size_t numVertices = vect_c.size(); - - myfile << "$NOD\n"; - myfile << numVertices <<"\n"; - - for(size_t i=0; i& qa = this->m_topology->getQuads(); - - myfile << qa.size() <<"\n"; - - for(size_t i=0; i bool QuadSetGeometryAlgorithms::mustComputeBBox() const diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetGeometryAlgorithms.h index 2891382c428f..f4d1a401f6b9 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetGeometryAlgorithms.h @@ -121,9 +121,6 @@ class TetrahedronSetGeometryAlgorithms : public TriangleSetGeometryAlgorithms &indices) const; void getTetraInBall(const Coord& c, Real r, sofa::type::vector &indices) const; - /** \brief Write the current mesh into a msh file - */ - void writeMSHfile(const char *filename) const; /// finds the intersection point with plane which is defined by c and normal void getIntersectionPointWithPlane(const TetraID ind_ta, const sofa::type::Vec<3,Real>& planP0, const sofa::type::Vec<3,Real>& normal, sofa::type::vector< sofa::type::Vec<3,Real> >& intersectedPoint, SeqEdges& intersectedEdge); @@ -167,6 +164,9 @@ class TetrahedronSetGeometryAlgorithms : public TriangleSetGeometryAlgorithms& intersectedPoints, sofa::type::vector& intersectedEdgeID, Coord planePos, Coord planeNormal); int subDivideRestTetrahedronWithPlane(TetraID tetraIdx, sofa::type::vector& intersectedEdgeID, sofa::type::vector& intersectedPointID, Coord planeNormal, sofa::type::vector& toBeAddedTetra); + SOFA_ATTRIBUTE_DISABLED("v23.12", "v23.12", "Method writeMSHfile has been disabled. To export the topology as .gmsh file, use the sofa::component::io::mesh::MeshExporter.") + void writeMSHfile(const char *filename) const {msg_deprecated() << "Method writeMSHfile has been disabled. To export the topology as " << filename << " file, use the sofa::component::io::mesh::MeshExporter."; } + protected: Data d_showTetrahedraIndices; ///< Debug : view Tetrahedrons indices Data d_drawTetrahedra; ///< if true, draw the tetrahedra in the topology diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetGeometryAlgorithms.inl b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetGeometryAlgorithms.inl index 32a0223563d3..e15d1ca0bc8b 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetGeometryAlgorithms.inl +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetGeometryAlgorithms.inl @@ -1011,48 +1011,6 @@ const sofa::type::vector& TetrahedronSetGeometryAlgor } -/// Write the current mesh into a msh file -template -void TetrahedronSetGeometryAlgorithms::writeMSHfile(const char *filename) const -{ - std::ofstream myfile; - myfile.open (filename); - - const typename DataTypes::VecCoord& vect_c =(this->object->read(core::ConstVecCoordId::position())->getValue()); - - const size_t numVertices = vect_c.size(); - - myfile << "$NOD\n"; - myfile << numVertices <<"\n"; - - for (size_t i=0; i &tea = this->m_topology->getTetrahedra(); - - myfile << tea.size() <<"\n"; - - for (size_t i=0; i void TetrahedronSetGeometryAlgorithms::subDivideTetrahedronsWithPlane(sofa::type::vector< sofa::type::vector >& coefs, sofa::type::vector& intersectedEdgeID, Coord /*planePos*/, Coord planeNormal) { diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.h index 0e2722ce1b97..7dbf8f15891c 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.h @@ -284,10 +284,6 @@ class TriangleSetGeometryAlgorithms : public EdgeSetGeometryAlgorithms& dir) const; - /** \brief Write the current mesh into a msh file - */ - void writeMSHfile(const char *filename) const; - /** \brief This function will changed vertex index in triangles if normal from one to another triangle are in opposite direction. First triangle index is used as ground truth. Use option flipNormals if first triangle direction is wrong. */ @@ -354,7 +350,8 @@ class TriangleSetGeometryAlgorithms : public EdgeSetGeometryAlgorithms& edges, sofa::type::vector& new_points, sofa::type::vector& end_points, bool& reachBorder); - + SOFA_ATTRIBUTE_DISABLED("v23.12", "v23.12", "Method writeMSHfile has been disabled. To export the topology as .gmsh file, use the sofa::component::io::mesh::MeshExporter.") + void writeMSHfile(const char *filename) const {msg_deprecated() << "Method writeMSHfile has been disabled. To export the topology as " << filename << " file, use the sofa::component::io::mesh::MeshExporter."; } protected: Data showTriangleIndices; ///< Debug : view Triangle indices diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl index c0d8284e6344..1238347a6f76 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl @@ -2402,46 +2402,6 @@ int TriangleSetGeometryAlgorithms::getTriangleInDirection(PointID p, return -1; } -/// Write the current mesh into a msh file -template -void TriangleSetGeometryAlgorithms::writeMSHfile(const char *filename) const -{ - std::ofstream myfile; - myfile.open (filename); - - const typename DataTypes::VecCoord& vect_c =(this->object->read(core::ConstVecCoordId::position())->getValue()); - - const size_t numVertices = vect_c.size(); - - myfile << "$NOD\n"; - myfile << numVertices <<"\n"; - - for (size_t i=0; i &ta=this->m_topology->getTriangles(); - - myfile << ta.size() <<"\n"; - - for (size_t i=0; i void TriangleSetGeometryAlgorithms::reorderTrianglesOrientationFromNormals() From fca2b552f9b7e1c1bacdf4ec37e294a8485bbdeb Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 4 Oct 2023 14:39:32 +0200 Subject: [PATCH 06/60] [MultiThreading] Introduce parallel CG (#4138) * [MultiThreading] Introduce parallel CG * Setup task scheduler * implement multithreading * Add support for Mat3x3 * better scene * Move ParallelCompressedRowSparseMatrixMechanical in its own file * introduce inl file * Cleanup * Fix compilation * Fix compilation * Register parallel implementation * Fix compilation * Fix performances when inserting by block * add missing required plugin * add regression on the introduced scene --- .../plugins/MultiThreading/CMakeLists.txt | 6 + .../examples/ParallelCGLinearSolver.scn | 29 +++ .../iterative/ParallelCGLinearSolver.cpp | 69 ++++++ .../iterative/ParallelCGLinearSolver.h | 54 +++++ .../iterative/ParallelCGLinearSolver.inl | 44 ++++ ...allelCompressedRowSparseMatrixMechanical.h | 214 ++++++++++++++++++ .../RegressionStateScenes.regression-tests | 3 + 7 files changed, 419 insertions(+) create mode 100644 applications/plugins/MultiThreading/examples/ParallelCGLinearSolver.scn create mode 100644 applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.cpp create mode 100644 applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.h create mode 100644 applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.inl create mode 100644 applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h diff --git a/applications/plugins/MultiThreading/CMakeLists.txt b/applications/plugins/MultiThreading/CMakeLists.txt index 2fd3e18af254..b20572ddc1cd 100644 --- a/applications/plugins/MultiThreading/CMakeLists.txt +++ b/applications/plugins/MultiThreading/CMakeLists.txt @@ -12,6 +12,9 @@ set(HEADER_FILES src/MultiThreading/component/animationloop/StepTask.h src/MultiThreading/component/collision/detection/algorithm/ParallelBVHNarrowPhase.h src/MultiThreading/component/collision/detection/algorithm/ParallelBruteForceBroadPhase.h + src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.h + src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.inl + src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h src/MultiThreading/component/mapping/linear/BeamLinearMapping_mt.h src/MultiThreading/component/mapping/linear/BeamLinearMapping_mt.inl src/MultiThreading/component/mapping/linear/BeamLinearMapping_tasks.inl @@ -35,6 +38,7 @@ set(SOURCE_FILES src/MultiThreading/component/animationloop/AnimationLoopParallelScheduler.cpp src/MultiThreading/component/collision/detection/algorithm/ParallelBVHNarrowPhase.cpp src/MultiThreading/component/collision/detection/algorithm/ParallelBruteForceBroadPhase.cpp + src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.cpp src/MultiThreading/component/mapping/linear/BeamLinearMapping_mt.cpp src/MultiThreading/component/solidmechanics/fem/elastic/ParallelHexahedronFEMForceField.cpp src/MultiThreading/component/solidmechanics/fem/elastic/ParallelTetrahedronFEMForceField.cpp @@ -66,6 +70,7 @@ sofa_find_package(Sofa.Component.SolidMechanics.FEM.Elastic REQUIRED) sofa_find_package(Sofa.Component.Mapping.Linear REQUIRED) sofa_find_package(Sofa.Component.StateContainer REQUIRED) sofa_find_package(Sofa.Component.SolidMechanics.Spring REQUIRED) +sofa_find_package(Sofa.Component.LinearSolver.Iterative REQUIRED) add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) target_link_libraries(${PROJECT_NAME} Sofa.Simulation.Common) @@ -74,6 +79,7 @@ target_link_libraries(${PROJECT_NAME} Sofa.Component.SolidMechanics.FEM.Elastic) target_link_libraries(${PROJECT_NAME} Sofa.Component.Mapping.Linear) target_link_libraries(${PROJECT_NAME} Sofa.Component.StateContainer) target_link_libraries(${PROJECT_NAME} Sofa.Component.SolidMechanics.Spring) +target_link_libraries(${PROJECT_NAME} Sofa.Component.LinearSolver.Iterative) ## Install rules for the library and headers; CMake package configurations files sofa_create_package_with_targets( diff --git a/applications/plugins/MultiThreading/examples/ParallelCGLinearSolver.scn b/applications/plugins/MultiThreading/examples/ParallelCGLinearSolver.scn new file mode 100644 index 000000000000..aa3c803ebeac --- /dev/null +++ b/applications/plugins/MultiThreading/examples/ParallelCGLinearSolver.scn @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.cpp b/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.cpp new file mode 100644 index 000000000000..22cd5f3569b4 --- /dev/null +++ b/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.cpp @@ -0,0 +1,69 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#define SOFA_MULTITHREADING_PARALLELCGLINEARSOLVER_CPP +#include +#include +#include +#include +#include +#include +#include + +namespace multithreading::component::linearsolver::iterative +{ +template class SOFA_MULTITHREADING_PLUGIN_API ParallelCompressedRowSparseMatrixMechanical; +template class SOFA_MULTITHREADING_PLUGIN_API ParallelCompressedRowSparseMatrixMechanical>; +} + +using multithreading::component::linearsolver::iterative::ParallelCompressedRowSparseMatrixMechanical; + +template class SOFA_MULTITHREADING_PLUGIN_API +sofa::component::linearsystem::TypedMatrixLinearSystem< ParallelCompressedRowSparseMatrixMechanical, sofa::linearalgebra::FullVector >; +template class SOFA_MULTITHREADING_PLUGIN_API +sofa::component::linearsystem::MatrixLinearSystem< ParallelCompressedRowSparseMatrixMechanical, sofa::linearalgebra::FullVector >; +template class SOFA_MULTITHREADING_PLUGIN_API +sofa::component::linearsolver::MatrixLinearSolver< ParallelCompressedRowSparseMatrixMechanical, sofa::linearalgebra::FullVector >; + +template class SOFA_MULTITHREADING_PLUGIN_API +sofa::component::linearsystem::TypedMatrixLinearSystem< ParallelCompressedRowSparseMatrixMechanical>, sofa::linearalgebra::FullVector >; +template class SOFA_MULTITHREADING_PLUGIN_API +sofa::component::linearsystem::MatrixLinearSystem< ParallelCompressedRowSparseMatrixMechanical>, sofa::linearalgebra::FullVector >; +template class SOFA_MULTITHREADING_PLUGIN_API +sofa::component::linearsolver::MatrixLinearSolver< ParallelCompressedRowSparseMatrixMechanical>, sofa::linearalgebra::FullVector >; + +namespace multithreading::component::linearsolver::iterative +{ + +template class SOFA_MULTITHREADING_PLUGIN_API +ParallelCGLinearSolver< ParallelCompressedRowSparseMatrixMechanical, sofa::linearalgebra::FullVector >; + +template class SOFA_MULTITHREADING_PLUGIN_API +ParallelCGLinearSolver< ParallelCompressedRowSparseMatrixMechanical>, sofa::linearalgebra::FullVector >; + +int ParallelCGLinearSolverClass = sofa::core::RegisterObject("Linear system solver using the conjugate gradient iterative algorithm in parallel") + .add< ParallelCGLinearSolver< ParallelCompressedRowSparseMatrixMechanical, sofa::linearalgebra::FullVector > >(true) + .add< ParallelCGLinearSolver< ParallelCompressedRowSparseMatrixMechanical>, sofa::linearalgebra::FullVector > >(); + +const bool isParallelCGLinearSolverImplementationRegistered = + ParallelImplementationsRegistry::addEquivalentImplementations("CGLinearSolver", "ParallelCGLinearSolver"); + +} diff --git a/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.h b/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.h new file mode 100644 index 000000000000..e0618a8c5cfa --- /dev/null +++ b/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.h @@ -0,0 +1,54 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include + +namespace multithreading::component::linearsolver::iterative +{ + +template +class ParallelCGLinearSolver : + public sofa::component::linearsolver::iterative::CGLinearSolver, + public TaskSchedulerUser +{ +public: + SOFA_CLASS2(SOFA_TEMPLATE2(ParallelCGLinearSolver,TMatrix,TVector), + SOFA_TEMPLATE2(sofa::component::linearsolver::iterative::CGLinearSolver,TMatrix,TVector), + TaskSchedulerUser); + + using Matrix = TMatrix; + using Vector = TVector; + + void init() override; + + void solve(Matrix& A, Vector& x, Vector& b) override; +}; + +#if !defined(SOFA_MULTITHREADING_PARALLELCGLINEARSOLVER_CPP) +extern template class SOFA_MULTITHREADING_PLUGIN_API +ParallelCGLinearSolver< ParallelCompressedRowSparseMatrix, sofa::linearalgebra::FullVector >; +ParallelCGLinearSolver< ParallelCompressedRowSparseMatrix >, sofa::linearalgebra::FullVector >; +#endif + +} diff --git a/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.inl b/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.inl new file mode 100644 index 000000000000..372e833bf6c4 --- /dev/null +++ b/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCGLinearSolver.inl @@ -0,0 +1,44 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include + +namespace multithreading::component::linearsolver::iterative +{ + +template +void ParallelCGLinearSolver::init() +{ + Inherit1::init(); + initTaskScheduler(); +} + +template +void ParallelCGLinearSolver::solve( + Matrix& A, Vector& x, Vector& b) +{ + A.setTaskScheduler(this->m_taskScheduler); + Inherit1::solve(A, x, b); +} + +} diff --git a/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h b/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h new file mode 100644 index 000000000000..2f12e06811d6 --- /dev/null +++ b/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h @@ -0,0 +1,214 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include + +namespace multithreading::component::linearsolver::iterative +{ +using sofa::linearalgebra::CRSMechanicalPolicy; + + +/** + * Simplified equivalent of CompressedRowSparseMatrixMechanical where some + * methods are multithreaded. + */ +template +class ParallelCompressedRowSparseMatrixMechanical : public sofa::linearalgebra::BaseMatrix +{ + using Base = sofa::linearalgebra::CompressedRowSparseMatrixMechanical; + +public: + + using Real = typename Base::Real; + using Index = typename Base::Index; + + static constexpr sofa::Index NL = Base::NL; + static constexpr sofa::Index NC = Base::NC; + + static const char* Name() + { + static std::string name = std::string("Parallel") + std::string(Base::Name()); + return name.c_str(); + } + + Index rowSize() const override + { + return m_crs.rowSize(); + } + Index colSize() const override + { + return m_crs.colSize(); + } + + void clearRowCol(Index i) override + { + m_crs.clearRowCol(i); + } + + void clearRow(Index i) override + { + m_crs.clearRow(i); + } + + void clearCol(Index i) override + { + m_crs.clearCol(i); + } + + void set(Index i, Index j, double v) override + { + m_crs.set(i, j, v); + } + + Index rowBSize() const + { + return m_crs.rowBSize(); + } + + template static void vresize(Vec& vec, Index /*blockSize*/, Index totalSize) { vec.resize( totalSize ); } + template static void vresize(sofa::type::vector&vec, Index blockSize, Index /*totalSize*/) { vec.resize( blockSize ); } + + template static Real vget(const Vec& vec, Index i, Index j, Index k) { return vget( vec, i*j+k ); } + template static Real vget(const sofa::type::vector&vec, Index i, Index /*j*/, Index k) { return vec[i][k]; } + + static Real vget(const sofa::linearalgebra::BaseVector& vec, Index i) { return static_cast(vec.element(i)); } + template static Real2 vget(const sofa::linearalgebra::FullVector& vec, Index i) { return vec[i]; } + + + template static void vset(Vec& vec, Index i, Index j, Index k, Real v) { vset( vec, i*j+k, v ); } + template static void vset(sofa::type::vector&vec, Index i, Index /*j*/, Index k, Real v) { vec[i][k] = v; } + + static void vset(sofa::linearalgebra::BaseVector& vec, Index i, Real v) { vec.set(i, v); } + template static void vset(sofa::linearalgebra::FullVector& vec, Index i, Real2 v) { vec[i] = v; } + + template + void tmul(V1& res, const V2& vec) const + { + assert(vec.size() % bColSize() == 0); // vec.size() must be a multiple of block size. + + const_cast(&m_crs)->compress(); + vresize(res, this->rowBSize(), this->rowSize()); + sofa::simulation::parallelForEachRange(*m_taskScheduler, static_cast(0), m_crs.rowIndex.size(), + [this, &vec, &res](const auto& range) + { + for (auto xi = range.start; xi < range.end; ++xi) + { + sofa::type::Vec r; + // local block-sized vector to accumulate the product of the block row with the large vector + + // multiply the non-null blocks with the corresponding chunks of the large vector + typename Base::Range rowRange(m_crs.rowBegin[xi], m_crs.rowBegin[xi + 1]); + for (Index xj = rowRange.begin(); xj < rowRange.end(); ++xj) + { + // transfer a chunk of large vector to a local block-sized vector + sofa::type::Vec v; + //Index jN = colsIndex[xj] * NC; // scalar column index + for (Index bj = 0; bj < NC; ++bj) + { + v[bj] = vget(vec, m_crs.colsIndex[xj], NC, bj); + } + + // multiply the block with the local vector + const typename Base::Block& b = m_crs.colsValue[xj]; + // non-null block has block-indices (rowIndex[xi],colsIndex[xj]) and value colsValue[xj] + for (Index bi = 0; bi < NL; ++bi) + { + for (Index bj = 0; bj < NC; ++bj) + { + r[bi] += Base::traits::v(b, bi, bj) * v[bj]; + } + } + } + + // transfer the local result to the large result vector + //Index iN = rowIndex[xi] * NL; // scalar row index + for (Index bi = 0; bi < NL; ++bi) + { + vset(res, m_crs.rowIndex[xi], NL, bi, r[bi]); + } + } + }); + + } + + template + Vec operator*(const Vec& v) const + { + Vec res; + tmul( res, v ); + return res; + } + + SReal element(BaseMatrix::Index i, BaseMatrix::Index j) const override + { + return m_crs.element(i, j); + } + + void resize(BaseMatrix::Index nbRow, BaseMatrix::Index nbCol) override + { + m_crs.resize(nbRow, nbCol); + } + + void clear() override + { + m_crs.clear(); + } + + void add(BaseMatrix::Index row, BaseMatrix::Index col, double v) override + { + m_crs.add(row, col, v); + } + + void add(Index row, Index col, const sofa::type::Mat3x3d & _M) override + { + m_crs.add(row, col, _M); + } + + void add(Index row, Index col, const sofa::type::Mat3x3f & _M) override + { + m_crs.add(row, col, _M); + } + + void add(Index row, Index col, const sofa::type::Mat2x2d & _M) override + { + m_crs.BaseMatrix::add(row, col, _M); + } + + void add(Index row, Index col, const sofa::type::Mat2x2f & _M) override + { + m_crs.BaseMatrix::add(row, col, _M); + } + + void setTaskScheduler(sofa::simulation::TaskScheduler* taskScheduler) + { + m_taskScheduler = taskScheduler; + } + +private: + Base m_crs; + sofa::simulation::TaskScheduler* m_taskScheduler { nullptr }; +}; + +} diff --git a/applications/plugins/RegressionStateScenes.regression-tests b/applications/plugins/RegressionStateScenes.regression-tests index a014df8a1ab7..f89599f53302 100644 --- a/applications/plugins/RegressionStateScenes.regression-tests +++ b/applications/plugins/RegressionStateScenes.regression-tests @@ -7,3 +7,6 @@ SofaSphFluid/examples/SPHFluidForceField.scn 100 1e-4 1 1 SofaSphFluid/examples/SPHFluidForceField_benchmarks.scn 100 1e-4 1 1 SofaSphFluid/examples/SPHParticleSink.scn 100 1e-4 1 1 SofaSphFluid/examples/SPHParticleSource.scn 100 1e-4 1 1 + +### MultiThreading ### +MultiThreading/examples/ParallelCGLinearSolver.scn 100 1e-8 1 1 From 8c9d4792f2d06be407c9dac78d44023cdfcc8086 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 4 Oct 2023 14:40:31 +0200 Subject: [PATCH 07/60] [LinearSystem] Introduce constant sparsity matrix assembly (#4158) * [LinearSystem] Introduce constant sparsity matrix assembly * Fix unit test * Template the class to be able to specialize for other types of matrices * Try to fix unit tests * fix * fix * fix * fix * add unused --- Sofa/Component/LinearSystem/CMakeLists.txt | 8 + .../ConstantSparsityPatternSystem.cpp | 35 ++ .../ConstantSparsityPatternSystem.h | 113 +++++ .../ConstantSparsityPatternSystem.inl | 391 ++++++++++++++++++ .../linearsystem/CreateMatrixDispatcher.h | 66 +++ .../linearsystem/MatrixLinearSystem.h | 35 +- .../linearsystem/MatrixLinearSystem.inl | 132 ++++-- .../ConstantLocalMappedMatrix.h | 95 +++++ .../matrixaccumulators/ConstantLocalMatrix.h | 93 +++++ .../SparsityPatternLocalMappedMatrix.h | 77 ++++ .../SparsityPatternLocalMatrix.h | 100 +++++ .../tests/MatrixLinearSystem_test.cpp | 1 + .../ConstantSparsityPatternSystem.scn | 89 ++++ examples/Demos/caduceus.scn | 3 +- 14 files changed, 1179 insertions(+), 59 deletions(-) create mode 100644 Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.cpp create mode 100644 Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.h create mode 100644 Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.inl create mode 100644 Sofa/Component/LinearSystem/src/sofa/component/linearsystem/CreateMatrixDispatcher.h create mode 100644 Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMappedMatrix.h create mode 100644 Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMatrix.h create mode 100644 Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/SparsityPatternLocalMappedMatrix.h create mode 100644 Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/SparsityPatternLocalMatrix.h create mode 100644 examples/Component/LinearSystem/ConstantSparsityPatternSystem.scn diff --git a/Sofa/Component/LinearSystem/CMakeLists.txt b/Sofa/Component/LinearSystem/CMakeLists.txt index e34e4259c0c2..7e76b2cd48ce 100644 --- a/Sofa/Component/LinearSystem/CMakeLists.txt +++ b/Sofa/Component/LinearSystem/CMakeLists.txt @@ -9,6 +9,9 @@ set(HEADER_FILES ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/MatrixLinearSystem.inl ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/CompositeLinearSystem.h ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/CompositeLinearSystem.inl + ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/ConstantSparsityPatternSystem.h + ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/ConstantSparsityPatternSystem.inl + ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/CreateMatrixDispatcher.h ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/LinearSystemData.h ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/MappingGraph.h ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/MatrixFreeSystem.h @@ -20,6 +23,10 @@ set(HEADER_FILES ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/matrixaccumulators/AssemblingMappedMatrixAccumulator.h ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/matrixaccumulators/AssemblingMatrixAccumulator.h ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/matrixaccumulators/BaseAssemblingMatrixAccumulator.h + ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/matrixaccumulators/ConstantLocalMappedMatrix.h + ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/matrixaccumulators/ConstantLocalMatrix.h + ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/matrixaccumulators/SparsityPatternLocalMappedMatrix.h + ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/matrixaccumulators/SparsityPatternLocalMatrix.h ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/visitors/AssembleGlobalVectorFromLocalVectorVisitor.h ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/visitors/DispatchFromGlobalVectorToLocalVectorVisitor.h @@ -29,6 +36,7 @@ set(SOURCE_FILES ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/init.cpp ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/MatrixLinearSystem.cpp ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/CompositeLinearSystem.cpp + ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/ConstantSparsityPatternSystem.cpp ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/MappingGraph.cpp ${SOFACOMPONENTLINEARSOLVERLINEARSYSTEM_SOURCE_DIR}/TypedMatrixLinearSystem.cpp diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.cpp b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.cpp new file mode 100644 index 000000000000..46f83983d6c6 --- /dev/null +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.cpp @@ -0,0 +1,35 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#define SOFA_COMPONENT_LINEARSYSTEM_CONSTANTSPARSITYPATTERNSYSTEM_CPP +#include + +#include + +namespace sofa::component::linearsystem +{ + +template class SOFA_COMPONENT_LINEARSYSTEM_API ConstantSparsityPatternSystem, linearalgebra::FullVector >; + +int ConstantSparsityPatternSystemClass = core::RegisterObject("Linear system taking advantage of the constant sparsity pattern of the global matrix to speed up the matrix assembly. Do not use if sparsity pattern is not constant (topological changes, ...).") + .add, linearalgebra::FullVector>>(); + +} diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.h b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.h new file mode 100644 index 000000000000..ecadeaf838ba --- /dev/null +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.h @@ -0,0 +1,113 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include +#include + +namespace sofa::component::linearsystem +{ + +using core::matrixaccumulator::no_check_policy; + +/** + * Assembling method benefitting from the constant sparsity pattern of the linear system in order to increase the + * performances. + * + * This method must not be used if the sparsity pattern changes from a time step to another. + * + * The method uses the first iteration to build the data structures required to accelerate the matrix assembly, based + * on a constant sparsity pattern. + * + * First iteration: + * 1) During the accumulation of matrix contributions, the local matrix stores an ordered list of matrix elements (row + * and column) corresponding to the order of insertion. This order must not change along the simulation. + * 2) After the matrix assembly, the global matrix is compressed so that the ordered list of matrix elements can be + * converted into an ordered list of ids corresponding to locations in the values array of the compressed matrix. + * + * Second time step and after: + * 1) The local matrices assume the order of insertion did not change. Therefore, they rely only on the ordered list of + * ids to know where in the values array to insert the matrix contribution. The row and column ids are useless. + */ +template +class SOFA_COMPONENT_LINEARSYSTEM_API ConstantSparsityPatternSystem : public MatrixLinearSystem +{ +public: + SOFA_CLASS( + SOFA_TEMPLATE2(ConstantSparsityPatternSystem, TMatrix, TVector), + SOFA_TEMPLATE2(MatrixLinearSystem, TMatrix, TVector)); + + using Matrix = TMatrix; + using Vector = TVector; + using Real = typename TMatrix::Real; + + void applyProjectiveConstraints(const core::MechanicalParams* mparams) override; + void resizeSystem(sofa::Size n) override; + void clearSystem() override; + + using ConstantCRSMapping = std::unordered_map; + + bool isConstantSparsityPatternUsedYet() const; + +protected: + + void preAssembleSystem(const core::MechanicalParams* /*mparams*/) override; + + bool m_isConstantSparsityPatternUsedYet { false }; + std::unique_ptr m_constantCRSMapping; + sofa::type::vector m_constantCRSMappingMappedMatrices; + + + ConstantSparsityPatternSystem(); + + + template + void replaceLocalMatrices(const core::MechanicalParams* mparams, + LocalMatrixMaps& matrixMaps); + + template + void replaceLocalMatrixMapped(const core::MechanicalParams* mparams, LocalMatrixMaps& matrixMaps); + + template + void replaceLocalMatricesNonMapped(const core::MechanicalParams* mparams, LocalMatrixMaps& matrixMaps); + + + template + void reinitLocalMatrices(LocalMatrixMaps& matrixMaps); + + + static void buildHashTable(linearalgebra::CompressedRowSparseMatrix& M, ConstantCRSMapping& mapping); + + void makeCreateDispatcher() override; + +private: + template + static std::unique_ptr> makeCreateDispatcher(); +}; + +#if !defined(SOFA_COMPONENT_LINEARSYSTEM_CONSTANTSPARSITYPATTERNSYSTEM_CPP) +extern template class SOFA_COMPONENT_LINEARSYSTEM_API ConstantSparsityPatternSystem, linearalgebra::FullVector >; +#endif + + +} diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.inl b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.inl new file mode 100644 index 000000000000..565e95689b8e --- /dev/null +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.inl @@ -0,0 +1,391 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include +#include +#include +#include + +namespace sofa::component::linearsystem +{ + +template +ConstantSparsityPatternSystem::ConstantSparsityPatternSystem() + : Inherit1() +{ +} + +template +template +void ConstantSparsityPatternSystem::replaceLocalMatrixMapped(const core::MechanicalParams* mparams, LocalMatrixMaps& matrixMaps) +{ + for (auto& [component, localMatrixMap] : matrixMaps.mappedLocalMatrix) + { + for (auto& [states, localMatrix] : localMatrixMap) + { + if (auto* sparsityPatternMatrix = dynamic_cast*>(localMatrix)) + { + const auto& insertionOrderList = sparsityPatternMatrix->getInsertionOrderList(); + + const auto factor = Inherit1::template getContributionFactor(mparams, component); + + auto mat = sofa::core::objectmodel::New>(); + configureCreatedMatrixComponent(mat, component, factor, !this->notMuted()); + + msg_info() << "Replacing " << sparsityPatternMatrix->getPathName() << " (class " + << sparsityPatternMatrix->getClass()->className << ") by " << mat->getPathName() << " (class " + << mat->getClass()->className << ")"; + + mat->setMatrixSize(localMatrix->getMatrixSize()); + const auto& sharedMatrix = localMatrix->getMatrix(); + mat->shareMatrix(sharedMatrix); + + const auto it = std::find_if(this->m_localMappedMatrices.begin(), this->m_localMappedMatrices.end(), + [&sharedMatrix](const auto& el){ return el.second == sharedMatrix; }); + if (it != this->m_localMappedMatrices.end()) + { + const auto id = std::distance(this->m_localMappedMatrices.begin(), it); + const auto& mapping = m_constantCRSMappingMappedMatrices[id]; + mat->insertionOrderList.reserve(insertionOrderList.size()); + for (const auto& [row, col] : insertionOrderList) + { + mat->insertionOrderList.push_back(mapping.at(row + col * sharedMatrix->rows())); + } + } + else + { + dmsg_error() << "Cannot find a matrix for this component"; + } + + component->removeSlave(localMatrix); + localMatrix = mat.get(); + localMatrixMap[states] = mat.get(); + matrixMaps.componentLocalMatrix[component][states] = mat.get(); + + const auto& [mstate0, mstate1] = states; + if constexpr (c == Contribution::STIFFNESS) + { + this->m_stiffness[component].setMatrixAccumulator(mat.get(), mstate0, mstate1); + } + else if constexpr (c == Contribution::DAMPING) + { + this->m_damping[component].setMatrixAccumulator(mat.get(), mstate0, mstate1); + } + else if constexpr (c == Contribution::GEOMETRIC_STIFFNESS) + { + this->m_geometricStiffness[component].setMatrixAccumulator(mat.get(), mstate0, mstate1); + } + else if constexpr (c == Contribution::MASS) + { + this->m_mass[component] = mat.get(); + } + } + else + { + dmsg_error() << "not a sparsity pattern matrix"; + } + } + } +} + +template +template +void ConstantSparsityPatternSystem::replaceLocalMatricesNonMapped(const core::MechanicalParams* mparams, LocalMatrixMaps& matrixMaps) +{ + for (auto& [component, localMatrixMap] : matrixMaps.componentLocalMatrix) + { + for (auto& [states, localMatrix] : localMatrixMap) + { + if (auto* sparsityPatternMatrix = dynamic_cast*>(localMatrix)) + { + const auto& insertionOrderList = sparsityPatternMatrix->getInsertionOrderList(); + + SReal factor = Inherit1::template getContributionFactor(mparams, component); + + auto mat = sofa::core::objectmodel::New>(); + configureCreatedMatrixComponent(mat, component, factor, !this->notMuted()); + + msg_info() << "Replacing " << sparsityPatternMatrix->getPathName() << " (class " + << sparsityPatternMatrix->getClass()->className << ") by " << mat->getPathName() << " (class " + << mat->getClass()->className << ")"; + + mat->setMatrixSize(localMatrix->getMatrixSize()); + mat->setGlobalMatrix(this->getSystemMatrix()); + mat->setPositionInGlobalMatrix(localMatrix->getPositionInGlobalMatrix()); + + mat->insertionOrderList.reserve(insertionOrderList.size()); + for (const auto& [row, col] : insertionOrderList) + { + const auto flatIndex = row + col * this->getSystemMatrix()->rows(); + const auto it = m_constantCRSMapping->find(flatIndex); + if (it != m_constantCRSMapping->end()) + { + mat->insertionOrderList.push_back(it->second); + } + else + { + msg_error() << "Could not find index " << flatIndex << " (row " << row << + ", col " << col << ") in the hash table"; + } + } + + component->removeSlave(localMatrix); + + const auto& [mstate0, mstate1] = states; + if constexpr (c == Contribution::STIFFNESS) + { + this->m_stiffness[component].setMatrixAccumulator(mat.get(), mstate0, mstate1); + } + else if constexpr (c == Contribution::DAMPING) + { + this->m_damping[component].setMatrixAccumulator(mat.get(), mstate0, mstate1); + } + else if constexpr (c == Contribution::GEOMETRIC_STIFFNESS) + { + this->m_geometricStiffness[component].setMatrixAccumulator(mat.get(), mstate0, mstate1); + } + else if constexpr (c == Contribution::MASS) + { + this->m_mass[component] = mat.get(); + } + + localMatrix = mat.get(); + } + } + } +} + +template +template +void ConstantSparsityPatternSystem::replaceLocalMatrices(const core::MechanicalParams* mparams, + LocalMatrixMaps& matrixMaps) +{ + replaceLocalMatrixMapped(mparams, matrixMaps); + replaceLocalMatricesNonMapped(mparams, matrixMaps); +} + +template +template +void ConstantSparsityPatternSystem::reinitLocalMatrices(LocalMatrixMaps& matrixMaps) +{ + for (auto& [component, localMatrixMap] : matrixMaps.componentLocalMatrix) + { + for (auto& [states, localMatrix] : localMatrixMap) + { + if (auto* local = dynamic_cast* >(localMatrix)) + { + local->currentId = 0; + } + } + } +} + +template +void ConstantSparsityPatternSystem::buildHashTable(linearalgebra::CompressedRowSparseMatrix& M, ConstantCRSMapping& mapping) +{ + for (unsigned int it_rows_k = 0; it_rows_k < M.rowIndex.size() ; it_rows_k ++) + { + const auto row = M.rowIndex[it_rows_k]; + typename Matrix::Range rowRange( M.rowBegin[it_rows_k], M.rowBegin[it_rows_k+1] ); + for(auto xj = rowRange.begin() ; xj < rowRange.end() ; ++xj ) // for each non-null block + { + const auto col = M.colsIndex[xj]; + mapping.emplace(row + col * M.rows(), xj); + } + } +} + +template +void ConstantSparsityPatternSystem::applyProjectiveConstraints(const core::MechanicalParams* mparams) +{ + if (!isConstantSparsityPatternUsedYet()) + { + auto& M = *this->getSystemMatrix(); + M.compress(); + + m_constantCRSMapping = std::make_unique(); + + // build the hash table from the compressed matrix + buildHashTable(M, *m_constantCRSMapping); + + m_constantCRSMappingMappedMatrices.resize(this->m_localMappedMatrices.size()); + std::size_t i {}; + for (const auto& mat : this->m_localMappedMatrices) + { + mat.second->fullRows(); + buildHashTable(*mat.second, m_constantCRSMappingMappedMatrices[i++]); + } + + //replace the local matrix components by new ones that use the hash table + replaceLocalMatrices(mparams, this->template getLocalMatrixMap()); + replaceLocalMatrices(mparams, this->template getLocalMatrixMap()); + replaceLocalMatrices(mparams, this->template getLocalMatrixMap()); + replaceLocalMatrices(mparams, this->template getLocalMatrixMap()); + + m_isConstantSparsityPatternUsedYet = true; + } + else + { + dmsg_error_when(!this->getSystemMatrix()->btemp.empty()) << "Matrix is not compressed"; + for (const auto& mat : this->m_localMappedMatrices) + { + dmsg_error_when(!mat.second->btemp.empty()) << "Matrix is not compressed"; + } + } + + //the hash table and the ordered lists must be created BEFORE the application of the projective constraints + Inherit1::applyProjectiveConstraints(mparams); +} + +template +void ConstantSparsityPatternSystem::resizeSystem(sofa::Size n) +{ + this->allocateSystem(); + + if (this->getSystemMatrix()) + { + if (n != this->getSystemMatrix()->rowSize() || n != this->getSystemMatrix()->colSize()) + { + this->getSystemMatrix()->resize(n, n); + } + else + { + // In the CRS format, the pattern is unchanged from a time step to the next + // Only the values are reset to 0 + + auto& values = this->getSystemMatrix()->colsValue; + std::fill(values.begin(), values.end(), 0_sreal); + + for (auto& m : this->m_localMappedMatrices) + { + std::fill(m.second->colsValue.begin(), m.second->colsValue.end(), 0_sreal); + } + } + } + + this->resizeVectors(n); +} + +template +void ConstantSparsityPatternSystem::clearSystem() +{ + this->allocateSystem(); + + if (this->getSystemMatrix()) + { + if (!isConstantSparsityPatternUsedYet()) + { + this->getSystemMatrix()->clear(); + } + else + { + auto& values = this->getSystemMatrix()->colsValue; + std::fill(values.begin(), values.end(), 0_sreal); + + unsigned int i = 0; + for (auto& m : this->m_localMappedMatrices) + { + std::fill(m.second->colsValue.begin(), m.second->colsValue.end(), 0_sreal); + ++i; + } + + + } + } + + if (this->getRHSVector()) + { + this->getRHSVector()->clear(); + } + + if (this->getSolutionVector()) + { + this->getSolutionVector()->clear(); + } +} + +template +bool ConstantSparsityPatternSystem::isConstantSparsityPatternUsedYet() const +{ + return m_isConstantSparsityPatternUsedYet; +} + +template +void ConstantSparsityPatternSystem::preAssembleSystem(const core::MechanicalParams* mechanical_params) +{ + Inherit1::preAssembleSystem(mechanical_params); + + if (isConstantSparsityPatternUsedYet()) + { + // this->getSystemMatrix()->compressed = true; + for (const auto& mat : this->m_localMappedMatrices) + { + // mat.second->compressed = true; + } + + reinitLocalMatrices(this->template getLocalMatrixMap()); + reinitLocalMatrices(this->template getLocalMatrixMap()); + reinitLocalMatrices(this->template getLocalMatrixMap()); + reinitLocalMatrices(this->template getLocalMatrixMap()); + } +} + +template +void ConstantSparsityPatternSystem::makeCreateDispatcher() +{ + std::get>>(this->m_createDispatcher) = makeCreateDispatcher(); + std::get>>(this->m_createDispatcher) = makeCreateDispatcher(); + std::get>>(this->m_createDispatcher) = makeCreateDispatcher(); + std::get>>(this->m_createDispatcher) = makeCreateDispatcher(); +} + +template +template +std::unique_ptr> ConstantSparsityPatternSystem::makeCreateDispatcher() +{ + struct SparsityPatternMatrixDispatcher : CreateMatrixDispatcher + { + typename BaseAssemblingMatrixAccumulator::SPtr + createLocalMappedMatrix() override + { + return sofa::core::objectmodel::New>(); + } + + protected: + + typename BaseAssemblingMatrixAccumulator::SPtr + createLocalMatrix() const override + { + return sofa::core::objectmodel::New>(); + } + + typename BaseAssemblingMatrixAccumulator::SPtr + createLocalMatrixWithIndexChecking() const override + { + return sofa::core::objectmodel::New>(); + } + }; + + return std::make_unique(); +} + +} diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/CreateMatrixDispatcher.h b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/CreateMatrixDispatcher.h new file mode 100644 index 000000000000..7bbf95120911 --- /dev/null +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/CreateMatrixDispatcher.h @@ -0,0 +1,66 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include + +namespace sofa::component::linearsystem +{ + +/** + * Helper class used in matrix assembly, containing some factory methods that + * must be overriden to define the type of local matrices. + */ +template +struct CreateMatrixDispatcher +{ + virtual ~CreateMatrixDispatcher() = default; + + /** + * \brief Create a local matrix object for non-mapped components + * \param withIndexChecking If true, the returned local matrix checks the + * indices before inserting the contributions into the matrix. + * \return A pointer to a local matrix + */ + [[nodiscard]] typename BaseAssemblingMatrixAccumulator::SPtr createLocalMatrix(const bool withIndexChecking) const + { + if (withIndexChecking) + { + return createLocalMatrixWithIndexChecking(); + } + return createLocalMatrix(); + } + + /** + * \brief Create a local matrix object for mapped components + * \return A pointer to a local matrix + */ + [[nodiscard]] virtual typename BaseAssemblingMatrixAccumulator::SPtr createLocalMappedMatrix() = 0; + +protected: + + [[nodiscard]] virtual typename BaseAssemblingMatrixAccumulator::SPtr createLocalMatrix() const = 0; + [[nodiscard]] virtual typename BaseAssemblingMatrixAccumulator::SPtr createLocalMatrixWithIndexChecking() const = 0; + +}; + +} diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.h b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.h index 88560a5f81ae..7d73a7f2f7e4 100644 --- a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.h +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.h @@ -29,6 +29,7 @@ #include #include #include +#include #include namespace sofa::component::linearsystem @@ -99,6 +100,7 @@ class MatrixLinearSystem : public TypedMatrixLinearSystem std::map m_stiffness; std::map m_damping; std::map m_geometricStiffness; + std::map*> m_mass; /// List of shared local matrices under mappings sofa::type::vector< std::pair< @@ -220,6 +222,22 @@ class MatrixLinearSystem : public TypedMatrixLinearSystem /// Given a Mechanical State and its matrix, identifies the nodes affected by the matrix std::vector identifyAffectedDoFs(BaseMechanicalState* mstate, LocalMappedMatrixType* crs); + + /// An object with factory methods to create local matrices + std::tuple< + std::unique_ptr>, + std::unique_ptr>, + std::unique_ptr>, + std::unique_ptr> + > m_createDispatcher; + + /// Define the type of dispatcher, itself defining the type of local matrices + /// To override if matrix accumulation methods differs from this class. + virtual void makeCreateDispatcher(); + +private: + template + static std::unique_ptr> makeCreateDispatcher(); }; template @@ -229,10 +247,6 @@ struct LocalMatrixMaps using ComponentType = sofa::core::matrixaccumulator::get_component_type; using PairMechanicalStates = sofa::type::fixed_array; - /// List of local matrices that components will use to add their contributions - std::map< ComponentType*, ListMatrixType > accumulators; - /// The local matrix (value) that has been created and associated to a non-mapped component (key) - std::map< ComponentType*, BaseAssemblingMatrixAccumulator* > localMatrix; /// The local matrix (value) that has been created and associated to a mapped component (key) std::map< ComponentType*, std::map*> > mappedLocalMatrix; /// A verification strategy allowing to verify that the matrix indices provided are valid @@ -243,25 +257,14 @@ struct LocalMatrixMaps void clear() { - for (const auto [component, matrix] : localMatrix) - { - if (component) - { - component->removeSlave(matrix); - } - } - - for (const auto& [component, matrixMap] : mappedLocalMatrix) + for (const auto& [component, matrixMap] : componentLocalMatrix) { for (const auto& [pair, matrix] : matrixMap) { component->removeSlave(matrix); - matrix->reset(); } } - accumulators.clear(); - localMatrix.clear(); mappedLocalMatrix.clear(); indexVerificationStrategy.clear(); componentLocalMatrix.clear(); diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl index 028b592c046f..5caef5efa644 100644 --- a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl @@ -78,25 +78,21 @@ void MatrixLinearSystem::contribute(const core::MechanicalPara { if (Inherit1::template getContributionFactor(mparams, contributor) != 0._sreal) { - auto& accumulators = getLocalMatrixMap().accumulators[contributor]; - // if (!accumulators.empty()) + if constexpr (c == Contribution::STIFFNESS) { - if constexpr (c == Contribution::STIFFNESS) - { - contributor->buildStiffnessMatrix(&m_stiffness[contributor]); - } - else if constexpr (c == Contribution::MASS) - { - contributor->buildMassMatrix(&accumulators); - } - else if constexpr (c == Contribution::DAMPING) - { - contributor->buildDampingMatrix(&m_damping[contributor]); - } - else if constexpr (c == Contribution::GEOMETRIC_STIFFNESS) - { - contributor->buildGeometricStiffnessMatrix(&m_geometricStiffness[contributor]); - } + contributor->buildStiffnessMatrix(&m_stiffness[contributor]); + } + else if constexpr (c == Contribution::MASS) + { + contributor->buildMassMatrix(m_mass[contributor]); + } + else if constexpr (c == Contribution::DAMPING) + { + contributor->buildDampingMatrix(&m_damping[contributor]); + } + else if constexpr (c == Contribution::GEOMETRIC_STIFFNESS) + { + contributor->buildGeometricStiffnessMatrix(&m_geometricStiffness[contributor]); } } } @@ -648,7 +644,9 @@ void MatrixLinearSystem::associateLocalMatrixTo( msg_info() << "No local matrix found: a new local matrix of type " << mat->getClassName() << " (template " << mat->getTemplateName() - << ") is created and associated to " << component->getPathName(); + << ") is created and associated to " << component->getPathName() + << " for a contribution on states " << mstate0->getPathName() + << " and " << mstate1->getPathName(); auto insertResult = componentLocalMatrix.insert({pairs, mat}); it = insertResult.first; @@ -670,25 +668,26 @@ void MatrixLinearSystem::associateLocalMatrixTo( } else if constexpr (c == Contribution::MASS) { - matrixMaps.accumulators[component].push_back(mat); + m_mass[component] = mat; } + } - if (mstates.size() == 1) - { - matrixMaps.localMatrix.insert({component, mat}); - } + BaseAssemblingMatrixAccumulator* localMatrix = it->second; + if (!localMatrix) + { + dmsg_fatal() << "Local matrix is invalid"; } const auto matrixSize1 = mstate0->getMatrixSize(); const auto matrixSize2 = mstate1->getMatrixSize(); if (!isAnyMapped) // mapped components don't add their contributions directly into the global matrix { - it->second->setGlobalMatrix(this->getSystemMatrix()); + localMatrix->setGlobalMatrix(this->getSystemMatrix()); const auto position = this->m_mappingGraph.getPositionInGlobalMatrix(mstate0, mstate1); - it->second->setPositionInGlobalMatrix(position); + localMatrix->setPositionInGlobalMatrix(position); } - it->second->setMatrixSize({matrixSize1, matrixSize2}); + localMatrix->setMatrixSize({matrixSize1, matrixSize2}); if (strategy) { strategy->maxRowIndex = matrixSize1; @@ -698,23 +697,60 @@ void MatrixLinearSystem::associateLocalMatrixTo( } +template +void MatrixLinearSystem::makeCreateDispatcher() +{ + std::get>>(m_createDispatcher) = makeCreateDispatcher(); + std::get>>(m_createDispatcher) = makeCreateDispatcher(); + std::get>>(m_createDispatcher) = makeCreateDispatcher(); + std::get>>(m_createDispatcher) = makeCreateDispatcher(); +} + +template +template +std::unique_ptr> MatrixLinearSystem +::makeCreateDispatcher() +{ + struct MyCreateMatrixDispatcher : CreateMatrixDispatcher + { + typename BaseAssemblingMatrixAccumulator::SPtr + createLocalMappedMatrix() override + { + return sofa::core::objectmodel::New>(); + } + + protected: + + typename BaseAssemblingMatrixAccumulator::SPtr + createLocalMatrix() const override + { + return sofa::core::objectmodel::New>(); + } + + typename BaseAssemblingMatrixAccumulator::SPtr + createLocalMatrixWithIndexChecking() const override + { + return sofa::core::objectmodel::New>(); + } + }; + + return std::make_unique(); +} + /** - * Generic function to create a local matrix and associate it to a component + * Generic function to configure a local matrix and associate it to a component */ -template -TLocalMatrix* createLocalMatrixComponent( - typename TLocalMatrix::ComponentType* object, const SReal factor, bool printLog) +template +void configureCreatedMatrixComponent(typename BaseAssemblingMatrixAccumulator::SPtr mat, + typename BaseAssemblingMatrixAccumulator::ComponentType* object, const SReal factor, bool printLog) { - static_assert(std::is_base_of_v, "Template argument must be a BaseObject"); - const auto mat = sofa::core::objectmodel::New(); - constexpr std::string_view contribution = core::matrixaccumulator::GetContributionName(); + constexpr std::string_view contribution = core::matrixaccumulator::GetContributionName(); mat->setName(std::string(contribution) + "_matrix"); mat->f_printLog.setValue(printLog); mat->setFactor(factor); mat->associateObject(object); mat->addTag(core::objectmodel::Tag(core::behavior::tagSetupByMatrixLinearSystem)); object->addSlave(mat); - return mat.get(); } template @@ -722,17 +758,25 @@ template BaseAssemblingMatrixAccumulator* MatrixLinearSystem::createLocalMatrixT( sofa::core::matrixaccumulator::get_component_type* object, SReal factor) { + this->makeCreateDispatcher(); + auto& dispatcher = std::get>>(m_createDispatcher); + typename BaseAssemblingMatrixAccumulator::SPtr localMatrix = dispatcher->createLocalMatrix(d_checkIndices.getValue()); + configureCreatedMatrixComponent(localMatrix, object, factor, !this->notMuted()); + if (d_checkIndices.getValue()) { - auto mat = createLocalMatrixComponent >(object, factor, !this->notMuted()); - const auto it = getLocalMatrixMap().indexVerificationStrategy.find(object); - if (it != getLocalMatrixMap().indexVerificationStrategy.end()) + if (auto concreteLocalMatrix + = dynamic_cast*>(localMatrix.get())) { - mat->indexVerificationStrategy = it->second; + const auto it = getLocalMatrixMap().indexVerificationStrategy.find(object); + if (it != getLocalMatrixMap().indexVerificationStrategy.end()) + { + concreteLocalMatrix->indexVerificationStrategy = it->second; + } } - return mat; } - return createLocalMatrixComponent >(object, factor, !this->notMuted()); + + return localMatrix.get(); } template @@ -741,7 +785,11 @@ AssemblingMappedMatrixAccumulator::createLocalMappedMatrixT( sofa::core::matrixaccumulator::get_component_type* object, SReal factor) { - return createLocalMatrixComponent >(object, factor, !this->notMuted()); + this->makeCreateDispatcher(); + auto& dispatcher = std::get>>(m_createDispatcher); + typename BaseAssemblingMatrixAccumulator::SPtr m = dispatcher->createLocalMappedMatrix(); + configureCreatedMatrixComponent(m, object, factor, !this->notMuted()); + return dynamic_cast*>(m.get()); } template diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMappedMatrix.h b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMappedMatrix.h new file mode 100644 index 000000000000..c426a2bb7bc0 --- /dev/null +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMappedMatrix.h @@ -0,0 +1,95 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include + +namespace sofa::component::linearsystem +{ + + +template +class ConstantLocalMappedMatrix : + public ConstantLocalMatrix, c>, + public AssemblingMappedMatrixAccumulator +{ +public: + SOFA_CLASS2(ConstantLocalMappedMatrix, + SOFA_TEMPLATE2(ConstantLocalMatrix, linearalgebra::CompressedRowSparseMatrix, c), + SOFA_TEMPLATE2(AssemblingMappedMatrixAccumulator, c, TBlockType)); + using ComponentType = typename Inherit1::ComponentType; + + using Inherit1::add; + +protected: + void add(const no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, float value) override; + void add(const no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, double value) override; + void add(const no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, float>& value) override; + void add(const no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, double>& value) override; +}; + + +template +void ConstantLocalMappedMatrix::add(const no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, + float value) +{ + SOFA_UNUSED(row); + SOFA_UNUSED(col); + this->m_mappedMatrix->colsValue[this->insertionOrderList[this->currentId++]] += this->m_cachedFactor * value; +} + +template +void ConstantLocalMappedMatrix::add(const no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, + double value) +{ + SOFA_UNUSED(row); + SOFA_UNUSED(col); + this->m_mappedMatrix->colsValue[this->insertionOrderList[this->currentId++]] += this->m_cachedFactor * value; +} + +template +void ConstantLocalMappedMatrix::add(const no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, + const sofa::type::Mat<3, 3, float>& value) +{ + for (sofa::SignedIndex i = 0; i < 3; ++i) + { + for (sofa::SignedIndex j = 0; j < 3; ++j) + { + this->add(row + i, col + j, value(i, j)); + } + } +} + +template +void ConstantLocalMappedMatrix::add(const no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, + const sofa::type::Mat<3, 3, double>& value) +{ + for (sofa::SignedIndex i = 0; i < 3; ++i) + { + for (sofa::SignedIndex j = 0; j < 3; ++j) + { + this->add(row + i, col + j, value(i, j)); + } + } +} + +} diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMatrix.h b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMatrix.h new file mode 100644 index 000000000000..cdb9a88978cc --- /dev/null +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMatrix.h @@ -0,0 +1,93 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include + +namespace sofa::component::linearsystem +{ +/** + * Local matrix using the insertion order to insert the value directly into the compressed matrix + */ +template +class ConstantLocalMatrix : public virtual AssemblingMatrixAccumulator +{ +public: + SOFA_CLASS(ConstantLocalMatrix, AssemblingMatrixAccumulator); + using ComponentType = typename Inherit1::ComponentType; + + using Inherit1::add; + + sofa::type::vector insertionOrderList; + std::size_t currentId {}; + +protected: + + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, float value) override; + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, double value) override; + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, float>& value) override; + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, double>& value) override; + +}; + +template +void ConstantLocalMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, float value) +{ + static_cast(this->m_globalMatrix)->colsValue[insertionOrderList[currentId++]] + += this->m_cachedFactor * value; +} + +template +void ConstantLocalMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, double value) +{ + static_cast(this->m_globalMatrix)->colsValue[insertionOrderList[currentId++]] + += this->m_cachedFactor * value; +} + +template +void ConstantLocalMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, + const sofa::type::Mat<3, 3, float>& value) +{ + for (sofa::SignedIndex i = 0; i < 3; ++i) + { + for (sofa::SignedIndex j = 0; j < 3; ++j) + { + this->add(core::matrixaccumulator::no_check, row + i, col + j, value(i, j)); + } + } +} + +template +void ConstantLocalMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, + const sofa::type::Mat<3, 3, double>& value) +{ + for (sofa::SignedIndex i = 0; i < 3; ++i) + { + for (sofa::SignedIndex j = 0; j < 3; ++j) + { + this->add(core::matrixaccumulator::no_check, row + i, col + j, value(i, j)); + } + } +} + + +} diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/SparsityPatternLocalMappedMatrix.h b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/SparsityPatternLocalMappedMatrix.h new file mode 100644 index 000000000000..c4e53b3c28c7 --- /dev/null +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/SparsityPatternLocalMappedMatrix.h @@ -0,0 +1,77 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include +#include + +namespace sofa::component::linearsystem +{ + +template +class SparsityPatternLocalMappedMatrix : + public SparsityPatternLocalMatrix, + public AssemblingMappedMatrixAccumulator +{ +public: + SOFA_CLASS2(SparsityPatternLocalMappedMatrix, SparsityPatternLocalMatrix, SOFA_TEMPLATE2(AssemblingMappedMatrixAccumulator, c, TBlockType)); + using ComponentType = typename Inherit1::ComponentType; + + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, float value) override; + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, double value) override; + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, float>& value) override; + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, double>& value) override; +}; + + +template +void SparsityPatternLocalMappedMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, + float value) +{ + this->insertionOrderList.emplace_back(row + this->m_cachedPositionInGlobalMatrix[0], col + this->m_cachedPositionInGlobalMatrix[1]); + Inherit2::add(core::matrixaccumulator::no_check, row, col, value); +} + +template +void SparsityPatternLocalMappedMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, + double value) +{ + this->insertionOrderList.emplace_back(row + this->m_cachedPositionInGlobalMatrix[0], col + this->m_cachedPositionInGlobalMatrix[1]); + Inherit2::add(core::matrixaccumulator::no_check, row, col, value); +} + +template +void SparsityPatternLocalMappedMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, + const sofa::type::Mat<3, 3, float>& value) +{ + Inherit1::add(core::matrixaccumulator::no_check, row, col, value); +} + +template +void SparsityPatternLocalMappedMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, + const sofa::type::Mat<3, 3, double>& value) +{ + Inherit1::add(core::matrixaccumulator::no_check, row, col, value); +} + + +} diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/SparsityPatternLocalMatrix.h b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/SparsityPatternLocalMatrix.h new file mode 100644 index 000000000000..907e00a508b0 --- /dev/null +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/SparsityPatternLocalMatrix.h @@ -0,0 +1,100 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +#include + +namespace sofa::component::linearsystem +{ + + +/** + * Local matrix used to collect the order values are inserted into the matrix + * This local matrix is used only once. + */ +template +class SparsityPatternLocalMatrix : public virtual AssemblingMatrixAccumulator +{ +public: + SOFA_CLASS(SparsityPatternLocalMatrix, SOFA_TEMPLATE2(AssemblingMatrixAccumulator, c, TStrategy)); + using ComponentType = typename Inherit1::ComponentType; + + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, float value) override; + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, double value) override; + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, float>& value) override; + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, double>& value) override; + + using Row = sofa::SignedIndex; + using Col = sofa::SignedIndex; + + [[nodiscard]] + const sofa::type::vector >& getInsertionOrderList() const + { return insertionOrderList; } + +protected: + + sofa::type::vector > insertionOrderList; +}; + + +template +void SparsityPatternLocalMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, float value) +{ + insertionOrderList.emplace_back(row + this->m_cachedPositionInGlobalMatrix[0], col + this->m_cachedPositionInGlobalMatrix[1]); + Inherit1::add(core::matrixaccumulator::no_check, row, col, value); +} + +template +void SparsityPatternLocalMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, double value) +{ + insertionOrderList.emplace_back(row + this->m_cachedPositionInGlobalMatrix[0], col + this->m_cachedPositionInGlobalMatrix[1]); + Inherit1::add(core::matrixaccumulator::no_check, row, col, value); +} + +template +void SparsityPatternLocalMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, + const sofa::type::Mat<3, 3, float>& value) +{ + for (sofa::SignedIndex i = 0; i < 3; ++i) + { + for (sofa::SignedIndex j = 0; j < 3; ++j) + { + this->add(core::matrixaccumulator::no_check, row + i, col + j, value(i, j)); + } + } +} + +template +void SparsityPatternLocalMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, + const sofa::type::Mat<3, 3, double>& value) +{ + for (sofa::SignedIndex i = 0; i < 3; ++i) + { + for (sofa::SignedIndex j = 0; j < 3; ++j) + { + this->add(core::matrixaccumulator::no_check, row + i, col + j, value(i, j)); + } + } +} + + +} diff --git a/Sofa/Component/LinearSystem/tests/MatrixLinearSystem_test.cpp b/Sofa/Component/LinearSystem/tests/MatrixLinearSystem_test.cpp index c3680628582f..a1e0825af215 100644 --- a/Sofa/Component/LinearSystem/tests/MatrixLinearSystem_test.cpp +++ b/Sofa/Component/LinearSystem/tests/MatrixLinearSystem_test.cpp @@ -115,6 +115,7 @@ TEST(LinearSystem, MatrixSystem_springForceField) //Create the Mechanical Object and define its positions auto mstate = sofa::core::objectmodel::New >(); + mstate->setName("mstate"); root->addObject(mstate); mstate->resize(2); auto writeAccessor = mstate->writePositions(); diff --git a/examples/Component/LinearSystem/ConstantSparsityPatternSystem.scn b/examples/Component/LinearSystem/ConstantSparsityPatternSystem.scn new file mode 100644 index 000000000000..db3ae28eb81d --- /dev/null +++ b/examples/Component/LinearSystem/ConstantSparsityPatternSystem.scn @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/Demos/caduceus.scn b/examples/Demos/caduceus.scn index 16e49cdb5dd8..81eb50261f54 100644 --- a/examples/Demos/caduceus.scn +++ b/examples/Demos/caduceus.scn @@ -48,7 +48,8 @@ - + + From 863b524c06822a941b5376eab89b7ac289b71329 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 4 Oct 2023 17:49:54 +0200 Subject: [PATCH 08/60] [LinearSystem] Assemble non-mapped and mapped matrices in parallel (#4172) * [LinearSystem] Introduce constant sparsity matrix assembly * Fix unit test * Template the class to be able to specialize for other types of matrices * Try to fix unit tests * add unused * Add timers * Fix compilation on Ubuntu * Fix typo * Default value set to false --------- Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --- .../linearsystem/MatrixLinearSystem.h | 18 ++ .../linearsystem/MatrixLinearSystem.inl | 198 ++++++++++++++++-- .../core/MechanicalStatesMatrixAccumulators.h | 2 - 3 files changed, 204 insertions(+), 14 deletions(-) diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.h b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.h index 7d73a7f2f7e4..c51f111d555c 100644 --- a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.h +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.h @@ -80,6 +80,7 @@ class MatrixLinearSystem : public TypedMatrixLinearSystem Data< bool > d_applyProjectiveConstraints; ///< If true, projective constraints are applied on the global matrix Data< bool > d_applyMappedComponents; ///< If true, mapped components contribute to the global matrix Data< bool > d_checkIndices; ///< If true, indices are verified before being added in to the global matrix, favoring security over speed + Data< bool > d_parallelAssemblyIndependentMatrices; ///< If true, independent matrices (global matrix vs mapped matrices) are assembled in parallel protected: @@ -102,6 +103,18 @@ class MatrixLinearSystem : public TypedMatrixLinearSystem std::map m_geometricStiffness; std::map*> m_mass; + struct IndependentContributors + { + std::map m_stiffness; + std::map m_damping; + std::map m_geometricStiffness; + std::map*> m_mass; + int id {}; + }; + + sofa::type::vector m_independentContributors; + + /// List of shared local matrices under mappings sofa::type::vector< std::pair< PairMechanicalStates, @@ -116,6 +129,9 @@ class MatrixLinearSystem : public TypedMatrixLinearSystem template void contribute(const core::MechanicalParams* mparams); + template + void contribute(const core::MechanicalParams* mparams, IndependentContributors& contributors); + void assembleSystem(const core::MechanicalParams* mparams) override; /** @@ -123,6 +139,8 @@ class MatrixLinearSystem : public TypedMatrixLinearSystem */ void makeLocalMatrixGroups(const core::MechanicalParams* mparams); + void makeIndependentLocalMatrixGroups(); + /** * Create the matrix accumulators and associate them to all components that have a contribution */ diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl index 5caef5efa644..54964cd34fa7 100644 --- a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include using sofa::simulation::mechanicalvisitor::MechanicalIdentityBlocksInJacobianVisitor; @@ -59,6 +61,8 @@ MatrixLinearSystem::MatrixLinearSystem() , d_applyProjectiveConstraints(initData(&d_applyProjectiveConstraints, true, "applyProjectiveConstraints", "If true, projective constraints are applied on the global matrix")) , d_applyMappedComponents (initData(&d_applyMappedComponents, true, "applyMappedComponents", "If true, mapped components contribute to the global matrix")) , d_checkIndices (initData(&d_checkIndices, false, "checkIndices", "If true, indices are verified before being added in to the global matrix, favoring security over speed")) + , d_parallelAssemblyIndependentMatrices + (initData(&d_parallelAssemblyIndependentMatrices, false, "parallelAssemblyIndependentMatrices", "If true, independent matrices (global matrix vs mapped matrices) are assembled in parallel")) { this->addUpdateCallback("updateCheckIndices", {&d_checkIndices}, [this](const core::DataTracker& t) { @@ -98,6 +102,55 @@ void MatrixLinearSystem::contribute(const core::MechanicalPara } } +template +template +void MatrixLinearSystem::contribute( + const core::MechanicalParams* mparams, + IndependentContributors& contributors) +{ + if constexpr (c == Contribution::STIFFNESS) + { + for (auto& [component, stiffnessMatrix] : contributors.m_stiffness) + { + if (Inherit1::template getContributionFactor(mparams, component) != 0._sreal) + { + component->buildStiffnessMatrix(&stiffnessMatrix); + } + } + } + else if constexpr (c == Contribution::MASS) + { + for (auto& [component, massMatrix] : contributors.m_mass) + { + if (Inherit1::template getContributionFactor(mparams, component) != 0._sreal) + { + component->buildMassMatrix(massMatrix); + } + } + } + else if constexpr (c == Contribution::DAMPING) + { + for (auto& [component, dampingMatrix] : contributors.m_damping) + { + if (Inherit1::template getContributionFactor(mparams, component) != 0._sreal) + { + component->buildDampingMatrix(&dampingMatrix); + } + } + } + else if constexpr (c == Contribution::GEOMETRIC_STIFFNESS) + { + for (auto& [component, geometricStiffnessMatrix] : contributors.m_geometricStiffness) + { + if (Inherit1::template getContributionFactor(mparams, component) != 0._sreal) + { + component->buildGeometricStiffnessMatrix(&geometricStiffnessMatrix); + + } + } + } +} + template void MatrixLinearSystem::assembleSystem(const core::MechanicalParams* mparams) { @@ -112,26 +165,59 @@ void MatrixLinearSystem::assembleSystem(const core::Mechanical { SCOPED_TIMER_VARNAME(buildMatricesTimer, "buildMatrices"); - if (d_assembleStiffness.getValue()) - { - contribute(mparams); - } + simulation::TaskScheduler* taskScheduler = simulation::MainTaskSchedulerFactory::createInRegistry(); + assert(taskScheduler); - if (d_assembleMass.getValue()) + if (d_parallelAssemblyIndependentMatrices.getValue() && taskScheduler && taskScheduler->getThreadCount() < 1) { - contribute(mparams); + taskScheduler->init(0); } - if (d_assembleDamping.getValue()) - { - contribute(mparams); - } + const simulation::ForEachExecutionPolicy execution = d_parallelAssemblyIndependentMatrices.getValue() ? + simulation::ForEachExecutionPolicy::PARALLEL : + simulation::ForEachExecutionPolicy::SEQUENTIAL; - if (d_assembleGeometricStiffness.getValue()) + const bool assembleStiffness = d_assembleStiffness.getValue(); + const bool assembleMass = d_assembleMass.getValue(); + const bool assembleDamping = d_assembleDamping.getValue(); + const bool assembleGeometricStiffness = d_assembleGeometricStiffness.getValue(); + + int counter{}; + for (auto& c : m_independentContributors) { - contribute(mparams); + c.id = counter++; } + simulation::forEach(execution, *taskScheduler, + m_independentContributors.begin(), m_independentContributors.end(), + [this, mparams, assembleStiffness, assembleMass, assembleDamping, assembleGeometricStiffness](IndependentContributors& contributors) + { + helper::ScopedAdvancedTimer timerContributors("buildContributors" + std::to_string(contributors.id)); + + if (assembleStiffness) + { + helper::ScopedAdvancedTimer timerStiffness("buildStiffness" + std::to_string(contributors.id)); + contribute(mparams, contributors); + } + + if (assembleMass) + { + helper::ScopedAdvancedTimer timerMass("buildMass" + std::to_string(contributors.id)); + contribute(mparams, contributors); + } + + if (assembleDamping) + { + helper::ScopedAdvancedTimer timerDamping("buildDamping" + std::to_string(contributors.id)); + contribute(mparams, contributors); + } + + if (assembleGeometricStiffness) + { + helper::ScopedAdvancedTimer timerGeometricStiffness("buildGeometricStiffness" + std::to_string(contributors.id)); + contribute(mparams, contributors); + } + }); } if (d_applyMappedComponents.getValue() && m_mappingGraph.hasAnyMapping()) @@ -459,6 +545,91 @@ void MatrixLinearSystem::makeLocalMatrixGroups(const core::Mec } } +template +void MatrixLinearSystem::makeIndependentLocalMatrixGroups() +{ + m_independentContributors.clear(); + + IndependentContributors nonMappedContributors; + IndependentContributors mappedContributors; + + for (auto& [component, localMatrix] : m_stiffness) + { + const auto& mappedMatrices = getLocalMatrixMap().mappedLocalMatrix; + if (mappedMatrices.find(component) == mappedMatrices.end()) //this component is not mapped + { + //confirmation that this component is not mapped: + if (m_mappingGraph.hasAnyMappingInput(component)) + { + dmsg_error() << "A mapped component has no mapped local matrix. This should not happen."; + continue; + } + + nonMappedContributors.m_stiffness.insert({component, localMatrix}); + } + else + { + mappedContributors.m_stiffness.insert({component, localMatrix}); + } + } + + for (auto& [component, localMatrix] : m_damping) + { + const auto& mappedMatrices = getLocalMatrixMap().mappedLocalMatrix; + if (mappedMatrices.find(component) == mappedMatrices.end()) //this component is not mapped + { + //confirmation that this component is not mapped: + if (m_mappingGraph.hasAnyMappingInput(component)) + { + dmsg_error() << "A mapped component has no mapped local matrix. This should not happen."; + continue; + } + + nonMappedContributors.m_damping.insert({component, localMatrix}); + } + else + { + mappedContributors.m_damping.insert({component, localMatrix}); + } + } + + for (auto& [component, localMatrix] : m_geometricStiffness) + { + const auto& mappedMatrices = getLocalMatrixMap().mappedLocalMatrix; + if (mappedMatrices.find(component) == mappedMatrices.end()) //this component is not mapped + { + nonMappedContributors.m_geometricStiffness.insert({component, localMatrix}); + } + else + { + mappedContributors.m_geometricStiffness.insert({component, localMatrix}); + } + } + + for (auto& [component, localMatrix] : m_mass) + { + const auto& mappedMatrices = getLocalMatrixMap().mappedLocalMatrix; + if (mappedMatrices.find(component) == mappedMatrices.end()) //this component is not mapped + { + //confirmation that this component is not mapped: + if (m_mappingGraph.hasAnyMappingInput(component)) + { + dmsg_error() << "A mapped component has no mapped local matrix. This should not happen."; + continue; + } + + nonMappedContributors.m_mass.insert({component, localMatrix}); + } + else + { + mappedContributors.m_mass.insert({component, localMatrix}); + } + } + + m_independentContributors.push_back(nonMappedContributors); + m_independentContributors.push_back(mappedContributors); +} + template void MatrixLinearSystem::cleanLocalMatrices() { @@ -470,6 +641,8 @@ void MatrixLinearSystem::cleanLocalMatrices() m_stiffness.clear(); m_damping.clear(); m_geometricStiffness.clear(); + m_mass.clear(); + m_independentContributors.clear(); } template @@ -556,6 +729,7 @@ void MatrixLinearSystem::associateLocalMatrixToComponents(cons } makeLocalMatrixGroups(mparams); + makeIndependentLocalMatrixGroups(); } } diff --git a/Sofa/framework/Core/src/sofa/core/MechanicalStatesMatrixAccumulators.h b/Sofa/framework/Core/src/sofa/core/MechanicalStatesMatrixAccumulators.h index 77377caecad8..cbb16d9ad662 100644 --- a/Sofa/framework/Core/src/sofa/core/MechanicalStatesMatrixAccumulators.h +++ b/Sofa/framework/Core/src/sofa/core/MechanicalStatesMatrixAccumulators.h @@ -53,8 +53,6 @@ class MechanicalStatesMatrixAccumulators MechanicalStatesMatrixAccumulators() = default; virtual ~MechanicalStatesMatrixAccumulators() = default; - MechanicalStatesMatrixAccumulators(const MechanicalStatesMatrixAccumulators&) = delete; - void operator=(const MechanicalStatesMatrixAccumulators&) = delete; private: From b76e0ffc286c657287847f81b4c7eed1687825f8 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Thu, 5 Oct 2023 06:07:06 +0900 Subject: [PATCH 09/60] [LinearSolver.Direct] SparseLDL: Fix crash in addJMInvJtLocal (#4180) use std vector to fix suspicious memory error Co-authored-by: erik pernod --- .../src/sofa/component/linearsolver/direct/SparseLDLSolver.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl index feaaf6dc0883..37b7b529e3d4 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl @@ -248,7 +248,7 @@ bool SparseLDLSolver::doAddJMInvJtLocal(ResMat simulation::forEachRange(execution, *taskScheduler, 0u, JlocalRowSize, [&data, this, fact, &mutex, result, JlocalRowSize](const auto& range) { - sofa::type::vector > triplets; + std::vector > triplets; triplets.reserve(JlocalRowSize * (range.end - range.start)); for (auto j = range.start; j != range.end; ++j) From 0b68075ed04b328aff6fb245ba8842d3ccb56a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20L=C3=BCbke?= Date: Thu, 5 Oct 2023 08:47:09 +0200 Subject: [PATCH 10/60] [GUI.Qt] Fix libQGLViewer cmake install (#4198) Update CMakeLists.txt This commit fixes issue https://github.com/sofa-framework/sofa/issues/4196#issue-1912081028: Co-authored-by: erik pernod --- Sofa/GUI/Qt/libQGLViewer/QGLViewer/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Sofa/GUI/Qt/libQGLViewer/QGLViewer/CMakeLists.txt b/Sofa/GUI/Qt/libQGLViewer/QGLViewer/CMakeLists.txt index 20c630b12ed2..51850801cf30 100644 --- a/Sofa/GUI/Qt/libQGLViewer/QGLViewer/CMakeLists.txt +++ b/Sofa/GUI/Qt/libQGLViewer/QGLViewer/CMakeLists.txt @@ -47,6 +47,12 @@ set(HEADER_FILES mouseGrabber.h quaternion.h vec.h + camera.h + frame.h + keyFrameInterpolator.h + manipulatedCameraFrame.h + manipulatedFrame.h + qglviewer.h ) set(SOURCE_FILES VRender/BSPSortMethod.cpp @@ -115,7 +121,7 @@ sofa_create_package_with_targets( PACKAGE_NAME ${PROJECT_NAME} PACKAGE_VERSION ${PROJECT_VERSION} TARGETS ${PROJECT_NAME} - INCLUDE_INSTALL_DIR "extlibs/${PROJECT_NAME}/${PROJECT_NAME}" + INCLUDE_INSTALL_DIR "extlibs" ) # Qt deployment From 977614f44ea39b6a1c68e988532f05859a98a8c4 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 5 Oct 2023 10:31:33 +0200 Subject: [PATCH 11/60] [BatchGUI] Show progress bar (#4168) * [BatchGUI] Show progress bar * Move progress bar in a class * Update cxxopts to allow unknown parameters * add option to hide the progress bar * Move extlib into a dedicated folder + license --- Sofa/GUI/Batch/CMakeLists.txt | 3 + .../GUI/Batch/src/sofa/gui/batch/BatchGUI.cpp | 24 +- Sofa/GUI/Batch/src/sofa/gui/batch/BatchGUI.h | 1 + .../Batch/src/sofa/gui/batch/ProgressBar.cpp | 102 + .../Batch/src/sofa/gui/batch/ProgressBar.h | 57 + .../src/sofa/gui/batch/indicators/LICENSE.txt | 21 + .../sofa/gui/batch/indicators/indicators.hpp | 3243 +++++++++++++++++ Sofa/GUI/Common/CMakeLists.txt | 2 +- .../src/sofa/gui/common/ArgumentParser.cpp | 2 +- .../src/sofa/gui/common/ArgumentParser.h | 2 +- 10 files changed, 3450 insertions(+), 7 deletions(-) create mode 100644 Sofa/GUI/Batch/src/sofa/gui/batch/ProgressBar.cpp create mode 100644 Sofa/GUI/Batch/src/sofa/gui/batch/ProgressBar.h create mode 100644 Sofa/GUI/Batch/src/sofa/gui/batch/indicators/LICENSE.txt create mode 100644 Sofa/GUI/Batch/src/sofa/gui/batch/indicators/indicators.hpp diff --git a/Sofa/GUI/Batch/CMakeLists.txt b/Sofa/GUI/Batch/CMakeLists.txt index aad3c29e7bfb..e379f849ecb1 100644 --- a/Sofa/GUI/Batch/CMakeLists.txt +++ b/Sofa/GUI/Batch/CMakeLists.txt @@ -7,11 +7,14 @@ set(HEADER_FILES ${SOFAGUIBATCH_ROOT}/config.h.in ${SOFAGUIBATCH_ROOT}/init.h ${SOFAGUIBATCH_ROOT}/BatchGUI.h + ${SOFAGUIBATCH_ROOT}/ProgressBar.h + ${SOFAGUIBATCH_ROOT}/indicators/indicators.hpp ) set(SOURCE_FILES ${SOFAGUIBATCH_ROOT}/init.cpp ${SOFAGUIBATCH_ROOT}/BatchGUI.cpp + ${SOFAGUIBATCH_ROOT}/ProgressBar.cpp ) sofa_find_package(Sofa.GUI.Common REQUIRED) diff --git a/Sofa/GUI/Batch/src/sofa/gui/batch/BatchGUI.cpp b/Sofa/GUI/Batch/src/sofa/gui/batch/BatchGUI.cpp index 9065ed4bb4c7..c2ea6014614f 100644 --- a/Sofa/GUI/Batch/src/sofa/gui/batch/BatchGUI.cpp +++ b/Sofa/GUI/Batch/src/sofa/gui/batch/BatchGUI.cpp @@ -34,6 +34,8 @@ #include #include #include +#include + namespace sofa::gui::batch { @@ -74,8 +76,14 @@ int BatchGUI::mainLoop() sofa::simulation::Visitor::ctime_t rt = sofa::helper::system::thread::CTime::getRefTime(); sofa::simulation::Visitor::ctime_t t = sofa::helper::system::thread::CTime::getFastTime(); - signed int i = 1; //one simulatin step is animated above - + signed int i = 1; //one simulation step is animated above + + std::unique_ptr progressBar; + if (!hideProgressBar) + { + progressBar = std::make_unique(nbIter); + } + while (i <= nbIter || nbIter == -1) { if (i != nbIter) @@ -105,9 +113,13 @@ int BatchGUI::mainLoop() } } + if (progressBar) + { + progressBar->tick(); + } + i++; } - } return 0; } @@ -186,7 +198,11 @@ int BatchGUI::RegisterGUIParameters(ArgumentParser* argumentParser) "(only batch) Number of iterations of the simulation", BatchGUI::OnNbIterChange ); - //Parses the string and passes it to setNumIterations as argument + argumentParser->addArgument( + cxxopts::value(hideProgressBar)->default_value("false"), + "hideProgressBar", + "if defined, hides the progress bar" + ); return 0; } diff --git a/Sofa/GUI/Batch/src/sofa/gui/batch/BatchGUI.h b/Sofa/GUI/Batch/src/sofa/gui/batch/BatchGUI.h index 38fdd17b761d..91cb614b7752 100644 --- a/Sofa/GUI/Batch/src/sofa/gui/batch/BatchGUI.h +++ b/Sofa/GUI/Batch/src/sofa/gui/batch/BatchGUI.h @@ -83,6 +83,7 @@ class SOFA_GUI_BATCH_API BatchGUI : public common::BaseGUI std::string filename; static signed int nbIter; static std::string nbIterInp; + inline static bool hideProgressBar { false }; /// Return true if the timer output string has a json string and the timer is setup to output json static bool canExportJson(const std::string& timerOutputStr, const std::string& timerId); diff --git a/Sofa/GUI/Batch/src/sofa/gui/batch/ProgressBar.cpp b/Sofa/GUI/Batch/src/sofa/gui/batch/ProgressBar.cpp new file mode 100644 index 000000000000..566f965d1af6 --- /dev/null +++ b/Sofa/GUI/Batch/src/sofa/gui/batch/ProgressBar.cpp @@ -0,0 +1,102 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation; either version 2 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#include +#include "indicators/indicators.hpp" +#include + +namespace sofa::gui::batch +{ +ProgressBar::ProgressBar(const int nbIterations) + : m_nbIterations(nbIterations) + , m_currentNbIterations(1) +{ + if (nbIterations != -1) + { + m_progressBar = std::make_unique( + indicators::option::BarWidth{50}, + indicators::option::Start{"\r["}, + indicators::option::Fill{"#"}, + indicators::option::Lead{"#"}, + indicators::option::Remainder{"-"}, + indicators::option::End{"]"}, + indicators::option::PostfixText{}, + indicators::option::ForegroundColor{indicators::Color::cyan}, + indicators::option::FontStyles{std::vector{indicators::FontStyle::bold}} + ); + } + else + { + m_indeterminateProgressBar = std::make_unique( + indicators::option::BarWidth{50}, + indicators::option::Start{"\r["}, + indicators::option::Fill{"."}, + indicators::option::Lead{"<==>"}, + indicators::option::End{"]"}, + indicators::option::PostfixText{}, + indicators::option::ForegroundColor{indicators::Color::cyan}, + indicators::option::FontStyles{std::vector{indicators::FontStyle::bold}} + ); + } + + indicators::show_console_cursor(false); + m_lastTick = std::chrono::high_resolution_clock::now(); +} + +ProgressBar::~ProgressBar() +{ + indicators::show_console_cursor(true); +} + +bool ProgressBar::isDurationFromLastTickEnough() const +{ + const auto now = std::chrono::high_resolution_clock::now(); + const std::chrono::duration durationFromLastTick = now - m_lastTick; + constexpr auto minimumDuration = std::chrono::milliseconds(1000 / 30); // 30Hz + return durationFromLastTick < minimumDuration; +} + +void ProgressBar::tick() +{ + //checking that enough time has passed to update the progress bar + //otherwise it could slow down the simulation, printing too often in the console + if (m_currentNbIterations < m_nbIterations - 1 && isDurationFromLastTickEnough()) + { + ++m_currentNbIterations; + return; + } + + if (m_nbIterations != -1 && m_progressBar) + { + m_progressBar->set_option(indicators::option::PostfixText{std::to_string(m_currentNbIterations) + "/" + std::to_string(m_nbIterations)}); + m_progressBar->set_progress(100 * m_currentNbIterations / m_nbIterations); + } + else if (m_nbIterations == -1 && m_indeterminateProgressBar) + { + m_indeterminateProgressBar->tick(); + m_indeterminateProgressBar->set_option(indicators::option::PostfixText{std::to_string(m_currentNbIterations)}); + } + + m_lastTick = std::chrono::high_resolution_clock::now(); + ++m_currentNbIterations; +} + +} diff --git a/Sofa/GUI/Batch/src/sofa/gui/batch/ProgressBar.h b/Sofa/GUI/Batch/src/sofa/gui/batch/ProgressBar.h new file mode 100644 index 000000000000..572a2484d03a --- /dev/null +++ b/Sofa/GUI/Batch/src/sofa/gui/batch/ProgressBar.h @@ -0,0 +1,57 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation; either version 2 of the License, or (at your option) * +* any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once +#include +#include +#include + +namespace indicators +{ + class ProgressBar; + class IndeterminateProgressBar; +} + +namespace sofa::gui::batch +{ + +class SOFA_GUI_BATCH_API ProgressBar +{ +public: + explicit ProgressBar(const int nbIterations); + + ~ProgressBar(); + + void tick(); + +private: + + std::unique_ptr m_progressBar; + std::unique_ptr m_indeterminateProgressBar; + + int m_nbIterations{1}; + int m_currentNbIterations{}; + + bool isDurationFromLastTickEnough() const; + std::chrono::time_point m_lastTick; +}; + +} diff --git a/Sofa/GUI/Batch/src/sofa/gui/batch/indicators/LICENSE.txt b/Sofa/GUI/Batch/src/sofa/gui/batch/indicators/LICENSE.txt new file mode 100644 index 000000000000..bcae1c6a2108 --- /dev/null +++ b/Sofa/GUI/Batch/src/sofa/gui/batch/indicators/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Pranav + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Sofa/GUI/Batch/src/sofa/gui/batch/indicators/indicators.hpp b/Sofa/GUI/Batch/src/sofa/gui/batch/indicators/indicators.hpp new file mode 100644 index 000000000000..234e1583e9c4 --- /dev/null +++ b/Sofa/GUI/Batch/src/sofa/gui/batch/indicators/indicators.hpp @@ -0,0 +1,3243 @@ + +#ifndef INDICATORS_COLOR +#define INDICATORS_COLOR + +namespace indicators { +enum class Color { grey, red, green, yellow, blue, magenta, cyan, white, unspecified }; +} + +#endif + + + +#ifndef INDICATORS_FONT_STYLE +#define INDICATORS_FONT_STYLE + +namespace indicators { +enum class FontStyle { bold, dark, italic, underline, blink, reverse, concealed, crossed }; +} + +#endif + + + +#ifndef INDICATORS_PROGRESS_TYPE +#define INDICATORS_PROGRESS_TYPE + +namespace indicators { +enum class ProgressType { incremental, decremental }; +} + +#endif + +//! +//! termcolor +//! ~~~~~~~~~ +//! +//! termcolor is a header-only c++ library for printing colored messages +//! to the terminal. Written just for fun with a help of the Force. +//! +//! :copyright: (c) 2013 by Ihor Kalnytskyi +//! :license: BSD, see LICENSE for details +//! + +#ifndef TERMCOLOR_HPP_ +#define TERMCOLOR_HPP_ + +#include +#include +#include + +// Detect target's platform and set some macros in order to wrap platform +// specific code this library depends on. +#if defined(_WIN32) || defined(_WIN64) +# define TERMCOLOR_TARGET_WINDOWS +#elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) +# define TERMCOLOR_TARGET_POSIX +#endif + +// If implementation has not been explicitly set, try to choose one based on +// target platform. +#if !defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) && !defined(TERMCOLOR_USE_WINDOWS_API) && !defined(TERMCOLOR_USE_NOOP) +# if defined(TERMCOLOR_TARGET_POSIX) +# define TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES +# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION +# elif defined(TERMCOLOR_TARGET_WINDOWS) +# define TERMCOLOR_USE_WINDOWS_API +# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION +# endif +#endif + +// These headers provide isatty()/fileno() functions, which are used for +// testing whether a standard stream refers to the terminal. +#if defined(TERMCOLOR_TARGET_POSIX) +# include +#elif defined(TERMCOLOR_TARGET_WINDOWS) +#if defined(_MSC_VER) +#if !defined(NOMINMAX) +#define NOMINMAX +#endif +#endif +# include +# include +#endif + + +namespace termcolor +{ + // Forward declaration of the `_internal` namespace. + // All comments are below. + namespace _internal + { + inline int colorize_index(); + inline FILE* get_standard_stream(const std::ostream& stream); + inline bool is_colorized(std::ostream& stream); + inline bool is_atty(const std::ostream& stream); + + #if defined(TERMCOLOR_TARGET_WINDOWS) + inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1); + #endif + } + + inline + std::ostream& colorize(std::ostream& stream) + { + stream.iword(_internal::colorize_index()) = 1L; + return stream; + } + + inline + std::ostream& nocolorize(std::ostream& stream) + { + stream.iword(_internal::colorize_index()) = 0L; + return stream; + } + + inline + std::ostream& reset(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[00m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, -1); + #endif + } + return stream; + } + + inline + std::ostream& bold(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[1m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& dark(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[2m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& italic(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[3m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& underline(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[4m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, COMMON_LVB_UNDERSCORE); + #endif + } + return stream; + } + + inline + std::ostream& blink(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[5m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& reverse(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[7m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& concealed(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[8m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& crossed(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[9m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + template inline + std::ostream& color(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + char command[12]; + std::snprintf(command, sizeof(command), "\033[38;5;%dm", code); + stream << command; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + template inline + std::ostream& on_color(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + char command[12]; + std::snprintf(command, sizeof(command), "\033[48;5;%dm", code); + stream << command; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + template inline + std::ostream& color(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + char command[20]; + std::snprintf(command, sizeof(command), "\033[38;2;%d;%d;%dm", r, g, b); + stream << command; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + template inline + std::ostream& on_color(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + char command[20]; + std::snprintf(command, sizeof(command), "\033[48;2;%d;%d;%dm", r, g, b); + stream << command; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + #endif + } + return stream; + } + + inline + std::ostream& grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[30m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + 0 // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[31m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[32m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN + ); + #endif + } + return stream; + } + + inline + std::ostream& yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[33m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[34m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE + ); + #endif + } + return stream; + } + + inline + std::ostream& magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[35m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[36m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN + ); + #endif + } + return stream; + } + + inline + std::ostream& white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[37m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED + ); + #endif + } + return stream; + } + + + inline + std::ostream& bright_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[90m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + 0 | FOREGROUND_INTENSITY // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[91m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[92m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[93m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[94m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[95m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[96m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& bright_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[97m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY + ); + #endif + } + return stream; + } + + + inline + std::ostream& on_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[40m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + 0 // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& on_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[41m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& on_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[42m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN + ); + #endif + } + return stream; + } + + inline + std::ostream& on_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[43m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& on_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[44m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE + ); + #endif + } + return stream; + } + + inline + std::ostream& on_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[45m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_RED + ); + #endif + } + return stream; + } + + inline + std::ostream& on_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[46m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE + ); + #endif + } + return stream; + } + + inline + std::ostream& on_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[47m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED + ); + #endif + } + + return stream; + } + + + inline + std::ostream& on_bright_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[100m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + 0 | BACKGROUND_INTENSITY // grey (black) + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[101m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[102m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[103m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[104m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[105m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[106m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY + ); + #endif + } + return stream; + } + + inline + std::ostream& on_bright_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { + #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) + stream << "\033[107m"; + #elif defined(TERMCOLOR_USE_WINDOWS_API) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY + ); + #endif + } + + return stream; + } + + + + //! Since C++ hasn't a way to hide something in the header from + //! the outer access, I have to introduce this namespace which + //! is used for internal purpose and should't be access from + //! the user code. + namespace _internal + { + // An index to be used to access a private storage of I/O streams. See + // colorize / nocolorize I/O manipulators for details. Due to the fact + // that static variables ain't shared between translation units, inline + // function with local static variable is used to do the trick and share + // the variable value between translation units. + inline int colorize_index() + { + static int colorize_index = std::ios_base::xalloc(); + return colorize_index; + } + + //! Since C++ hasn't a true way to extract stream handler + //! from the a given `std::ostream` object, I have to write + //! this kind of hack. + inline + FILE* get_standard_stream(const std::ostream& stream) + { + if (&stream == &std::cout) + return stdout; + else if ((&stream == &std::cerr) || (&stream == &std::clog)) + return stderr; + + return nullptr; + } + + // Say whether a given stream should be colorized or not. It's always + // true for ATTY streams and may be true for streams marked with + // colorize flag. + inline + bool is_colorized(std::ostream& stream) + { + return is_atty(stream) || static_cast(stream.iword(colorize_index())); + } + + //! Test whether a given `std::ostream` object refers to + //! a terminal. + inline + bool is_atty(const std::ostream& stream) + { + FILE* std_stream = get_standard_stream(stream); + + // Unfortunately, fileno() ends with segmentation fault + // if invalid file descriptor is passed. So we need to + // handle this case gracefully and assume it's not a tty + // if standard stream is not detected, and 0 is returned. + if (!std_stream) + return false; + + #if defined(TERMCOLOR_TARGET_POSIX) + return ::isatty(fileno(std_stream)); + #elif defined(TERMCOLOR_TARGET_WINDOWS) + return ::_isatty(_fileno(std_stream)); + #else + return false; + #endif + } + + #if defined(TERMCOLOR_TARGET_WINDOWS) + //! Change Windows Terminal colors attribute. If some + //! parameter is `-1` then attribute won't changed. + inline void win_change_attributes(std::ostream& stream, int foreground, int background) + { + // yeah, i know.. it's ugly, it's windows. + static WORD defaultAttributes = 0; + + // Windows doesn't have ANSI escape sequences and so we use special + // API to change Terminal output color. That means we can't + // manipulate colors by means of "std::stringstream" and hence + // should do nothing in this case. + if (!_internal::is_atty(stream)) + return; + + // get terminal handle + HANDLE hTerminal = INVALID_HANDLE_VALUE; + if (&stream == &std::cout) + hTerminal = GetStdHandle(STD_OUTPUT_HANDLE); + else if (&stream == &std::cerr) + hTerminal = GetStdHandle(STD_ERROR_HANDLE); + + // save default terminal attributes if it unsaved + if (!defaultAttributes) + { + CONSOLE_SCREEN_BUFFER_INFO info; + if (!GetConsoleScreenBufferInfo(hTerminal, &info)) + return; + defaultAttributes = info.wAttributes; + } + + // restore all default settings + if (foreground == -1 && background == -1) + { + SetConsoleTextAttribute(hTerminal, defaultAttributes); + return; + } + + // get current settings + CONSOLE_SCREEN_BUFFER_INFO info; + if (!GetConsoleScreenBufferInfo(hTerminal, &info)) + return; + + if (foreground != -1) + { + info.wAttributes &= ~(info.wAttributes & 0x0F); + info.wAttributes |= static_cast(foreground); + } + + if (background != -1) + { + info.wAttributes &= ~(info.wAttributes & 0xF0); + info.wAttributes |= static_cast(background); + } + + SetConsoleTextAttribute(hTerminal, info.wAttributes); + } + #endif // TERMCOLOR_TARGET_WINDOWS + + } // namespace _internal + +} // namespace termcolor + + +#undef TERMCOLOR_TARGET_POSIX +#undef TERMCOLOR_TARGET_WINDOWS + +#if defined(TERMCOLOR_AUTODETECTED_IMPLEMENTATION) +# undef TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES +# undef TERMCOLOR_USE_WINDOWS_API +#endif + +#endif // TERMCOLOR_HPP_ + + + +#ifndef INDICATORS_TERMINAL_SIZE +#define INDICATORS_TERMINAL_SIZE +#include + + +#if defined(_WIN32) +#include + +namespace indicators { + +static inline std::pair terminal_size() { + CONSOLE_SCREEN_BUFFER_INFO csbi; + int cols, rows; + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); + cols = csbi.srWindow.Right - csbi.srWindow.Left + 1; + rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; + return {static_cast(rows), static_cast(cols)}; +} + +static inline size_t terminal_width() { return terminal_size().second; } + +} // namespace indicators + +#else + +#include //ioctl() and TIOCGWINSZ +#include // for STDOUT_FILENO + +namespace indicators { + +static inline std::pair terminal_size() { + struct winsize size{}; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &size); + return {static_cast(size.ws_row), static_cast(size.ws_col)}; +} + +static inline size_t terminal_width() { return terminal_size().second; } + +} // namespace indicators + +#endif + +#endif + + +/* +Activity Indicators for Modern C++ +https://github.com/p-ranav/indicators + +Licensed under the MIT License . +SPDX-License-Identifier: MIT +Copyright (c) 2019 Dawid Pilarski . + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +#ifndef INDICATORS_SETTING +#define INDICATORS_SETTING + +#include +// #include +// #include +// #include +#include +#include +#include +#include +#include + +namespace indicators { + +namespace details { + +template struct if_else; + +template <> struct if_else { using type = std::true_type; }; + +template <> struct if_else { using type = std::false_type; }; + +template struct if_else_type; + +template struct if_else_type { + using type = True; +}; + +template struct if_else_type { + using type = False; +}; + +template struct conjuction; + +template <> struct conjuction<> : std::true_type {}; + +template +struct conjuction + : if_else_type>::type {}; + +template struct disjunction; + +template <> struct disjunction<> : std::false_type {}; + +template +struct disjunction + : if_else_type>::type {}; + +enum class ProgressBarOption { + bar_width = 0, + prefix_text, + postfix_text, + start, + end, + fill, + lead, + remainder, + max_postfix_text_len, + completed, + show_percentage, + show_elapsed_time, + show_remaining_time, + saved_start_time, + foreground_color, + spinner_show, + spinner_states, + font_styles, + hide_bar_when_complete, + min_progress, + max_progress, + progress_type, + stream +}; + +template struct Setting { + template ::value>::type> + explicit Setting(Args &&... args) : value(std::forward(args)...) {} + Setting(const Setting &) = default; + Setting(Setting &&) = default; + + static constexpr auto id = Id; + using type = T; + + T value{}; +}; + +template struct is_setting : std::false_type {}; + +template struct is_setting> : std::true_type {}; + +template +struct are_settings : if_else...>::value>::type {}; + +template <> struct are_settings<> : std::true_type {}; + +template struct is_setting_from_tuple; + +template struct is_setting_from_tuple> : std::true_type {}; + +template +struct is_setting_from_tuple> + : if_else...>::value>::type {}; + +template +struct are_settings_from_tuple + : if_else...>::value>::type {}; + +template struct always_true { static constexpr auto value = true; }; + +template Default &&get_impl(Default &&def) { + return std::forward(def); +} + +template +auto get_impl(Default && /*def*/, T &&first, Args &&... /*tail*/) -> + typename std::enable_if<(std::decay::type::id == Id), + decltype(std::forward(first))>::type { + return std::forward(first); +} + +template +auto get_impl(Default &&def, T && /*first*/, Args &&... tail) -> + typename std::enable_if<(std::decay::type::id != Id), + decltype(get_impl(std::forward(def), + std::forward(tail)...))>::type { + return get_impl(std::forward(def), std::forward(tail)...); +} + +template ::value, void>::type> +auto get(Default &&def, Args &&... args) + -> decltype(details::get_impl(std::forward(def), std::forward(args)...)) { + return details::get_impl(std::forward(def), std::forward(args)...); +} + +template using StringSetting = Setting; + +template using IntegerSetting = Setting; + +template using BooleanSetting = Setting; + +template struct option_idx; + +template +struct option_idx, counter> + : if_else_type<(Id == T::id), std::integral_constant, + option_idx, counter + 1>>::type {}; + +template struct option_idx, counter> { + static_assert(always_true<(ProgressBarOption)Id>::value, "No such option was found"); +}; + +template +auto get_value(Settings &&settings) + -> decltype((std::get::type>::value>( + std::declval()))) { + return std::get::type>::value>( + std::forward(settings)); +} + +} // namespace details + +namespace option { +using BarWidth = details::IntegerSetting; +using PrefixText = details::StringSetting; +using PostfixText = details::StringSetting; +using Start = details::StringSetting; +using End = details::StringSetting; +using Fill = details::StringSetting; +using Lead = details::StringSetting; +using Remainder = details::StringSetting; +using MaxPostfixTextLen = details::IntegerSetting; +using Completed = details::BooleanSetting; +using ShowPercentage = details::BooleanSetting; +using ShowElapsedTime = details::BooleanSetting; +using ShowRemainingTime = details::BooleanSetting; +using SavedStartTime = details::BooleanSetting; +using ForegroundColor = details::Setting; +using ShowSpinner = details::BooleanSetting; +using SpinnerStates = + details::Setting, details::ProgressBarOption::spinner_states>; +using HideBarWhenComplete = + details::BooleanSetting; +using FontStyles = + details::Setting, details::ProgressBarOption::font_styles>; +using MinProgress = details::IntegerSetting; +using MaxProgress = details::IntegerSetting; +using ProgressType = details::Setting; +using Stream = details::Setting; +} // namespace option +} // namespace indicators + +#endif + + +#ifndef INDICATORS_CURSOR_CONTROL +#define INDICATORS_CURSOR_CONTROL + +#if defined(_MSC_VER) +#if !defined(NOMINMAX) +#define NOMINMAX +#endif +#include +#include +#else +#include +#endif + +namespace indicators { + +#if defined(_MSC_VER) + +static inline void show_console_cursor(bool const show) { + HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_CURSOR_INFO cursorInfo; + + GetConsoleCursorInfo(out, &cursorInfo); + cursorInfo.bVisible = show; // set the cursor visibility + SetConsoleCursorInfo(out, &cursorInfo); +} + +static inline void erase_line() { + auto hStdout = GetStdHandle(STD_OUTPUT_HANDLE); + if (!hStdout) + return; + + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo(hStdout, &csbiInfo); + + COORD cursor; + + cursor.X = 0; + cursor.Y = csbiInfo.dwCursorPosition.Y; + + DWORD count = 0; + + FillConsoleOutputCharacterA(hStdout, ' ', csbiInfo.dwSize.X, cursor, &count); + + FillConsoleOutputAttribute(hStdout, csbiInfo.wAttributes, csbiInfo.dwSize.X, + cursor, &count); + + SetConsoleCursorPosition(hStdout, cursor); +} + +#else + +static inline void show_console_cursor(bool const show) { + std::fputs(show ? "\033[?25h" : "\033[?25l", stdout); +} + +static inline void erase_line() { + std::fputs("\r\033[K", stdout); +} + +#endif + +} // namespace indicators + +#endif + + +#ifndef INDICATORS_CURSOR_MOVEMENT +#define INDICATORS_CURSOR_MOVEMENT + +#if defined(_MSC_VER) +#if !defined(NOMINMAX) +#define NOMINMAX +#endif +#include +#include +#else +#include +#endif + +namespace indicators { + +#ifdef _MSC_VER + +static inline void move(int x, int y) { + auto hStdout = GetStdHandle(STD_OUTPUT_HANDLE); + if (!hStdout) + return; + + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo(hStdout, &csbiInfo); + + COORD cursor; + + cursor.X = csbiInfo.dwCursorPosition.X + x; + cursor.Y = csbiInfo.dwCursorPosition.Y + y; + SetConsoleCursorPosition(hStdout, cursor); +} + +static inline void move_up(int lines) { move(0, -lines); } +static inline void move_down(int lines) { move(0, -lines); } +static inline void move_right(int cols) { move(cols, 0); } +static inline void move_left(int cols) { move(-cols, 0); } + +#else + +static inline void move_up(int lines) { std::cout << "\033[" << lines << "A"; } +static inline void move_down(int lines) { std::cout << "\033[" << lines << "B"; } +static inline void move_right(int cols) { std::cout << "\033[" << cols << "C"; } +static inline void move_left(int cols) { std::cout << "\033[" << cols << "D"; } + +#endif + +} // namespace indicators + +#endif + + +#ifndef INDICATORS_STREAM_HELPER +#define INDICATORS_STREAM_HELPER + +// #include +#ifndef INDICATORS_DISPLAY_WIDTH +#define INDICATORS_DISPLAY_WIDTH + +#include +#include +#include +#include +#include + +namespace unicode { + +namespace details { + +/* + * This is an implementation of wcwidth() and wcswidth() (defined in + * IEEE Std 1002.1-2001) for Unicode. + * + * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html + * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html + * + * In fixed-width output devices, Latin characters all occupy a single + * "cell" position of equal width, whereas ideographic CJK characters + * occupy two such cells. Interoperability between terminal-line + * applications and (teletype-style) character terminals using the + * UTF-8 encoding requires agreement on which character should advance + * the cursor by how many cell positions. No established formal + * standards exist at present on which Unicode character shall occupy + * how many cell positions on character terminals. These routines are + * a first attempt of defining such behavior based on simple rules + * applied to data provided by the Unicode Consortium. + * + * For some graphical characters, the Unicode standard explicitly + * defines a character-cell width via the definition of the East Asian + * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes. + * In all these cases, there is no ambiguity about which width a + * terminal shall use. For characters in the East Asian Ambiguous (A) + * class, the width choice depends purely on a preference of backward + * compatibility with either historic CJK or Western practice. + * Choosing single-width for these characters is easy to justify as + * the appropriate long-term solution, as the CJK practice of + * displaying these characters as double-width comes from historic + * implementation simplicity (8-bit encoded characters were displayed + * single-width and 16-bit ones double-width, even for Greek, + * Cyrillic, etc.) and not any typographic considerations. + * + * Much less clear is the choice of width for the Not East Asian + * (Neutral) class. Existing practice does not dictate a width for any + * of these characters. It would nevertheless make sense + * typographically to allocate two character cells to characters such + * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be + * represented adequately with a single-width glyph. The following + * routines at present merely assign a single-cell width to all + * neutral characters, in the interest of simplicity. This is not + * entirely satisfactory and should be reconsidered before + * establishing a formal standard in this area. At the moment, the + * decision which Not East Asian (Neutral) characters should be + * represented by double-width glyphs cannot yet be answered by + * applying a simple rule from the Unicode database content. Setting + * up a proper standard for the behavior of UTF-8 character terminals + * will require a careful analysis not only of each Unicode character, + * but also of each presentation form, something the author of these + * routines has avoided to do so far. + * + * http://www.unicode.org/unicode/reports/tr11/ + * + * Markus Kuhn -- 2007-05-26 (Unicode 5.0) + * + * Permission to use, copy, modify, and distribute this software + * for any purpose and without fee is hereby granted. The author + * disclaims all warranties with regard to this software. + * + * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c + */ + +struct interval { + int first; + int last; +}; + +/* auxiliary function for binary search in interval table */ +static inline int bisearch(wchar_t ucs, const struct interval *table, int max) { + int min = 0; + int mid; + + if (ucs < table[0].first || ucs > table[max].last) + return 0; + while (max >= min) { + mid = (min + max) / 2; + if (ucs > table[mid].last) + min = mid + 1; + else if (ucs < table[mid].first) + max = mid - 1; + else + return 1; + } + + return 0; +} + +/* The following two functions define the column width of an ISO 10646 + * character as follows: + * + * - The null character (U+0000) has a column width of 0. + * + * - Other C0/C1 control characters and DEL will lead to a return + * value of -1. + * + * - Non-spacing and enclosing combining characters (general + * category code Mn or Me in the Unicode database) have a + * column width of 0. + * + * - SOFT HYPHEN (U+00AD) has a column width of 1. + * + * - Other format characters (general category code Cf in the Unicode + * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0. + * + * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) + * have a column width of 0. + * + * - Spacing characters in the East Asian Wide (W) or East Asian + * Full-width (F) category as defined in Unicode Technical + * Report #11 have a column width of 2. + * + * - All remaining characters (including all printable + * ISO 8859-1 and WGL4 characters, Unicode control characters, + * etc.) have a column width of 1. + * + * This implementation assumes that wchar_t characters are encoded + * in ISO 10646. + */ + +static inline int mk_wcwidth(wchar_t ucs) { + /* sorted list of non-overlapping intervals of non-spacing characters */ + /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ + static const struct interval combining[] = { + {0x0300, 0x036F}, {0x0483, 0x0486}, {0x0488, 0x0489}, + {0x0591, 0x05BD}, {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, + {0x05C4, 0x05C5}, {0x05C7, 0x05C7}, {0x0600, 0x0603}, + {0x0610, 0x0615}, {0x064B, 0x065E}, {0x0670, 0x0670}, + {0x06D6, 0x06E4}, {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, + {0x070F, 0x070F}, {0x0711, 0x0711}, {0x0730, 0x074A}, + {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, {0x0901, 0x0902}, + {0x093C, 0x093C}, {0x0941, 0x0948}, {0x094D, 0x094D}, + {0x0951, 0x0954}, {0x0962, 0x0963}, {0x0981, 0x0981}, + {0x09BC, 0x09BC}, {0x09C1, 0x09C4}, {0x09CD, 0x09CD}, + {0x09E2, 0x09E3}, {0x0A01, 0x0A02}, {0x0A3C, 0x0A3C}, + {0x0A41, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, + {0x0A70, 0x0A71}, {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC}, + {0x0AC1, 0x0AC5}, {0x0AC7, 0x0AC8}, {0x0ACD, 0x0ACD}, + {0x0AE2, 0x0AE3}, {0x0B01, 0x0B01}, {0x0B3C, 0x0B3C}, + {0x0B3F, 0x0B3F}, {0x0B41, 0x0B43}, {0x0B4D, 0x0B4D}, + {0x0B56, 0x0B56}, {0x0B82, 0x0B82}, {0x0BC0, 0x0BC0}, + {0x0BCD, 0x0BCD}, {0x0C3E, 0x0C40}, {0x0C46, 0x0C48}, + {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56}, {0x0CBC, 0x0CBC}, + {0x0CBF, 0x0CBF}, {0x0CC6, 0x0CC6}, {0x0CCC, 0x0CCD}, + {0x0CE2, 0x0CE3}, {0x0D41, 0x0D43}, {0x0D4D, 0x0D4D}, + {0x0DCA, 0x0DCA}, {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, + {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, + {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, + {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F71, 0x0F7E}, + {0x0F80, 0x0F84}, {0x0F86, 0x0F87}, {0x0F90, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102D, 0x1030}, + {0x1032, 0x1032}, {0x1036, 0x1037}, {0x1039, 0x1039}, + {0x1058, 0x1059}, {0x1160, 0x11FF}, {0x135F, 0x135F}, + {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, + {0x1772, 0x1773}, {0x17B4, 0x17B5}, {0x17B7, 0x17BD}, + {0x17C6, 0x17C6}, {0x17C9, 0x17D3}, {0x17DD, 0x17DD}, + {0x180B, 0x180D}, {0x18A9, 0x18A9}, {0x1920, 0x1922}, + {0x1927, 0x1928}, {0x1932, 0x1932}, {0x1939, 0x193B}, + {0x1A17, 0x1A18}, {0x1B00, 0x1B03}, {0x1B34, 0x1B34}, + {0x1B36, 0x1B3A}, {0x1B3C, 0x1B3C}, {0x1B42, 0x1B42}, + {0x1B6B, 0x1B73}, {0x1DC0, 0x1DCA}, {0x1DFE, 0x1DFF}, + {0x200B, 0x200F}, {0x202A, 0x202E}, {0x2060, 0x2063}, + {0x206A, 0x206F}, {0x20D0, 0x20EF}, {0x302A, 0x302F}, + {0x3099, 0x309A}, {0xA806, 0xA806}, {0xA80B, 0xA80B}, + {0xA825, 0xA826}, {0xFB1E, 0xFB1E}, {0xFE00, 0xFE0F}, + {0xFE20, 0xFE23}, {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, + {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, + {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x1D167, 0x1D169}, + {0x1D173, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, + {0x1D242, 0x1D244}, {0xE0001, 0xE0001}, {0xE0020, 0xE007F}, + {0xE0100, 0xE01EF}}; + + /* test for 8-bit control characters */ + if (ucs == 0) + return 0; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return -1; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, combining, sizeof(combining) / sizeof(struct interval) - 1)) + return 0; + + /* if we arrive here, ucs is not a combining or C0/C1 control character */ + + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + ucs == 0x2329 || ucs == 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && + ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd))); +} + +static inline int mk_wcswidth(const wchar_t *pwcs, size_t n) { + int w, width = 0; + + for (; *pwcs && n-- > 0; pwcs++) + if ((w = mk_wcwidth(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} + +/* + * The following functions are the same as mk_wcwidth() and + * mk_wcswidth(), except that spacing characters in the East Asian + * Ambiguous (A) category as defined in Unicode Technical Report #11 + * have a column width of 2. This variant might be useful for users of + * CJK legacy encodings who want to migrate to UCS without changing + * the traditional terminal character-width behaviour. It is not + * otherwise recommended for general use. + */ +static inline int mk_wcwidth_cjk(wchar_t ucs) { + /* sorted list of non-overlapping intervals of East Asian Ambiguous + * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */ + static const struct interval ambiguous[] = { + {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, + {0x00AA, 0x00AA}, {0x00AE, 0x00AE}, {0x00B0, 0x00B4}, + {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, + {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, + {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, + {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, + {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, + {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, + {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, + {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, + {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, + {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, + {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, + {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, + {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, + {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, + {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, + {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0391, 0x03A1}, + {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, {0x03C3, 0x03C9}, + {0x0401, 0x0401}, {0x0410, 0x044F}, {0x0451, 0x0451}, + {0x2010, 0x2010}, {0x2013, 0x2016}, {0x2018, 0x2019}, + {0x201C, 0x201D}, {0x2020, 0x2022}, {0x2024, 0x2027}, + {0x2030, 0x2030}, {0x2032, 0x2033}, {0x2035, 0x2035}, + {0x203B, 0x203B}, {0x203E, 0x203E}, {0x2074, 0x2074}, + {0x207F, 0x207F}, {0x2081, 0x2084}, {0x20AC, 0x20AC}, + {0x2103, 0x2103}, {0x2105, 0x2105}, {0x2109, 0x2109}, + {0x2113, 0x2113}, {0x2116, 0x2116}, {0x2121, 0x2122}, + {0x2126, 0x2126}, {0x212B, 0x212B}, {0x2153, 0x2154}, + {0x215B, 0x215E}, {0x2160, 0x216B}, {0x2170, 0x2179}, + {0x2190, 0x2199}, {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, + {0x21D4, 0x21D4}, {0x21E7, 0x21E7}, {0x2200, 0x2200}, + {0x2202, 0x2203}, {0x2207, 0x2208}, {0x220B, 0x220B}, + {0x220F, 0x220F}, {0x2211, 0x2211}, {0x2215, 0x2215}, + {0x221A, 0x221A}, {0x221D, 0x2220}, {0x2223, 0x2223}, + {0x2225, 0x2225}, {0x2227, 0x222C}, {0x222E, 0x222E}, + {0x2234, 0x2237}, {0x223C, 0x223D}, {0x2248, 0x2248}, + {0x224C, 0x224C}, {0x2252, 0x2252}, {0x2260, 0x2261}, + {0x2264, 0x2267}, {0x226A, 0x226B}, {0x226E, 0x226F}, + {0x2282, 0x2283}, {0x2286, 0x2287}, {0x2295, 0x2295}, + {0x2299, 0x2299}, {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, + {0x2312, 0x2312}, {0x2460, 0x24E9}, {0x24EB, 0x254B}, + {0x2550, 0x2573}, {0x2580, 0x258F}, {0x2592, 0x2595}, + {0x25A0, 0x25A1}, {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, + {0x25B6, 0x25B7}, {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, + {0x25C6, 0x25C8}, {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, + {0x25E2, 0x25E5}, {0x25EF, 0x25EF}, {0x2605, 0x2606}, + {0x2609, 0x2609}, {0x260E, 0x260F}, {0x2614, 0x2615}, + {0x261C, 0x261C}, {0x261E, 0x261E}, {0x2640, 0x2640}, + {0x2642, 0x2642}, {0x2660, 0x2661}, {0x2663, 0x2665}, + {0x2667, 0x266A}, {0x266C, 0x266D}, {0x266F, 0x266F}, + {0x273D, 0x273D}, {0x2776, 0x277F}, {0xE000, 0xF8FF}, + {0xFFFD, 0xFFFD}, {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}}; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, ambiguous, sizeof(ambiguous) / sizeof(struct interval) - 1)) + return 2; + + return mk_wcwidth(ucs); +} + +static inline int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n) { + int w, width = 0; + + for (; *pwcs && n-- > 0; pwcs++) + if ((w = mk_wcwidth_cjk(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} + +// convert UTF-8 string to wstring +#ifdef _MSC_VER +static inline std::wstring utf8_decode(const std::string& s) { + std::string curLocale = setlocale(LC_ALL, ""); + const char* _Source = s.c_str(); + size_t _Dsize = std::strlen(_Source) + 1; + wchar_t* _Dest = new wchar_t[_Dsize]; + size_t _Osize; + mbstowcs_s(&_Osize, _Dest, _Dsize, _Source, _Dsize); + std::wstring result = _Dest; + delete[] _Dest; + setlocale(LC_ALL, curLocale.c_str()); + return result; +} +#else +static inline std::wstring utf8_decode(const std::string& s) { + std::string curLocale = setlocale(LC_ALL, ""); + const char* _Source = s.c_str(); + size_t _Dsize = mbstowcs(NULL, _Source, 0) + 1; + wchar_t* _Dest = new wchar_t[_Dsize]; + wmemset(_Dest, 0, _Dsize); + mbstowcs(_Dest, _Source, _Dsize); + std::wstring result = _Dest; + delete[] _Dest; + setlocale(LC_ALL, curLocale.c_str()); + return result; +} +#endif + +} // namespace details + +static inline int display_width(const std::string &input) { + using namespace unicode::details; + return mk_wcswidth(utf8_decode(input).c_str(), input.size()); +} + +static inline int display_width(const std::wstring &input) { + return details::mk_wcswidth(input.c_str(), input.size()); +} + +} // namespace unicode + +#endif +// #include +// #include + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace indicators { +namespace details { + +inline void set_stream_color(std::ostream &os, Color color) { + switch (color) { + case Color::grey: + os << termcolor::grey; + break; + case Color::red: + os << termcolor::red; + break; + case Color::green: + os << termcolor::green; + break; + case Color::yellow: + os << termcolor::yellow; + break; + case Color::blue: + os << termcolor::blue; + break; + case Color::magenta: + os << termcolor::magenta; + break; + case Color::cyan: + os << termcolor::cyan; + break; + case Color::white: + os << termcolor::white; + break; + default: + assert(false); + } +} + +inline void set_font_style(std::ostream &os, FontStyle style) { + switch (style) { + case FontStyle::bold: + os << termcolor::bold; + break; + case FontStyle::dark: + os << termcolor::dark; + break; + case FontStyle::italic: + os << termcolor::italic; + break; + case FontStyle::underline: + os << termcolor::underline; + break; + case FontStyle::blink: + os << termcolor::blink; + break; + case FontStyle::reverse: + os << termcolor::reverse; + break; + case FontStyle::concealed: + os << termcolor::concealed; + break; + case FontStyle::crossed: + os << termcolor::crossed; + break; + default: + break; + } +} + +inline std::ostream &write_duration(std::ostream &os, std::chrono::nanoseconds ns) { + using namespace std; + using namespace std::chrono; + using days = duration>; + char fill = os.fill(); + os.fill('0'); + auto d = duration_cast(ns); + ns -= d; + auto h = duration_cast(ns); + ns -= h; + auto m = duration_cast(ns); + ns -= m; + auto s = duration_cast(ns); + if (d.count() > 0) + os << setw(2) << d.count() << "d:"; + if (h.count() > 0) + os << setw(2) << h.count() << "h:"; + os << setw(2) << m.count() << "m:" << setw(2) << s.count() << 's'; + os.fill(fill); + return os; +} + +class BlockProgressScaleWriter { +public: + BlockProgressScaleWriter(std::ostream &os, size_t bar_width) : os(os), bar_width(bar_width) {} + + std::ostream &write(float progress) { + std::string fill_text{"█"}; + std::vector lead_characters{" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉"}; + auto value = (std::min)(1.0f, (std::max)(0.0f, progress / 100.0f)); + auto whole_width = std::floor(value * bar_width); + auto remainder_width = fmod((value * bar_width), 1.0f); + auto part_width = std::floor(remainder_width * lead_characters.size()); + std::string lead_text = lead_characters[size_t(part_width)]; + if ((bar_width - whole_width - 1) < 0) + lead_text = ""; + for (size_t i = 0; i < whole_width; ++i) + os << fill_text; + os << lead_text; + for (size_t i = 0; i < (bar_width - whole_width - 1); ++i) + os << " "; + return os; + } + +private: + std::ostream &os; + size_t bar_width = 0; +}; + +class ProgressScaleWriter { +public: + ProgressScaleWriter(std::ostream &os, size_t bar_width, const std::string &fill, + const std::string &lead, const std::string &remainder) + : os(os), bar_width(bar_width), fill(fill), lead(lead), remainder(remainder) {} + + std::ostream &write(float progress) { + auto pos = static_cast(progress * bar_width / 100.0); + for (size_t i = 0, current_display_width = 0; i < bar_width;) { + std::string next; + + if (i < pos) { + next = fill; + current_display_width = unicode::display_width(fill); + } else if (i == pos) { + next = lead; + current_display_width = unicode::display_width(lead); + } else { + next = remainder; + current_display_width = unicode::display_width(remainder); + } + + i += current_display_width; + + if (i > bar_width) { + // `next` is larger than the allowed bar width + // fill with empty space instead + os << std::string((bar_width - (i - current_display_width)), ' '); + break; + } + + os << next; + } + return os; + } + +private: + std::ostream &os; + size_t bar_width = 0; + std::string fill; + std::string lead; + std::string remainder; +}; + +class IndeterminateProgressScaleWriter { +public: + IndeterminateProgressScaleWriter(std::ostream &os, size_t bar_width, const std::string &fill, + const std::string &lead) + : os(os), bar_width(bar_width), fill(fill), lead(lead) {} + + std::ostream &write(size_t progress) { + for (size_t i = 0; i < bar_width;) { + std::string next; + size_t current_display_width = 0; + + if (i < progress) { + next = fill; + current_display_width = unicode::display_width(fill); + } else if (i == progress) { + next = lead; + current_display_width = unicode::display_width(lead); + } else { + next = fill; + current_display_width = unicode::display_width(fill); + } + + i += current_display_width; + + if (i > bar_width) { + // `next` is larger than the allowed bar width + // fill with empty space instead + os << std::string((bar_width - (i - current_display_width)), ' '); + break; + } + + os << next; + } + return os; + } + +private: + std::ostream &os; + size_t bar_width = 0; + std::string fill; + std::string lead; +}; + +} // namespace details +} // namespace indicators + +#endif + + +#ifndef INDICATORS_PROGRESS_BAR +#define INDICATORS_PROGRESS_BAR + +// #include + +#include +#include +#include +#include +// #include +// #include +// #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace indicators { + +class ProgressBar { + using Settings = + std::tuple; + +public: + template ::type...>::value, + void *>::type = nullptr> + explicit ProgressBar(Args &&... args) + : settings_( + details::get( + option::BarWidth{100}, std::forward(args)...), + details::get( + option::PrefixText{}, std::forward(args)...), + details::get( + option::PostfixText{}, std::forward(args)...), + details::get( + option::Start{"["}, std::forward(args)...), + details::get( + option::End{"]"}, std::forward(args)...), + details::get( + option::Fill{"="}, std::forward(args)...), + details::get( + option::Lead{">"}, std::forward(args)...), + details::get( + option::Remainder{" "}, std::forward(args)...), + details::get( + option::MaxPostfixTextLen{0}, std::forward(args)...), + details::get( + option::Completed{false}, std::forward(args)...), + details::get( + option::ShowPercentage{false}, std::forward(args)...), + details::get( + option::ShowElapsedTime{false}, std::forward(args)...), + details::get( + option::ShowRemainingTime{false}, std::forward(args)...), + details::get( + option::SavedStartTime{false}, std::forward(args)...), + details::get( + option::ForegroundColor{Color::unspecified}, + std::forward(args)...), + details::get( + option::FontStyles{std::vector{}}, + std::forward(args)...), + details::get( + option::MinProgress{0}, std::forward(args)...), + details::get( + option::MaxProgress{100}, std::forward(args)...), + details::get( + option::ProgressType{ProgressType::incremental}, + std::forward(args)...), + details::get( + option::Stream{std::cout}, std::forward(args)...)) { + + // if progress is incremental, start from min_progress + // else start from max_progress + const auto type = get_value(); + if (type == ProgressType::incremental) + progress_ = get_value(); + else + progress_ = get_value(); + } + + template + void set_option(details::Setting &&setting) { + static_assert( + !std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); + std::lock_guard lock(mutex_); + get_value() = std::move(setting).value; + } + + template + void set_option(const details::Setting &setting) { + static_assert( + !std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); + std::lock_guard lock(mutex_); + get_value() = setting.value; + } + + void + set_option(const details::Setting< + std::string, details::ProgressBarOption::postfix_text> &setting) { + std::lock_guard lock(mutex_); + get_value() = setting.value; + if (setting.value.length() > + get_value()) { + get_value() = + setting.value.length(); + } + } + + void set_option( + details::Setting + &&setting) { + std::lock_guard lock(mutex_); + get_value() = + std::move(setting).value; + auto &new_value = get_value(); + if (new_value.length() > + get_value()) { + get_value() = + new_value.length(); + } + } + + void set_progress(size_t new_progress) { + { + std::lock_guard lock(mutex_); + progress_ = new_progress; + } + + save_start_time(); + print_progress(); + } + + void tick() { + { + std::lock_guard lock{mutex_}; + const auto type = get_value(); + if (type == ProgressType::incremental) + progress_ += 1; + else + progress_ -= 1; + } + save_start_time(); + print_progress(); + } + + size_t current() { + std::lock_guard lock{mutex_}; + return (std::min)( + progress_, + size_t(get_value())); + } + + bool is_completed() const { + return get_value(); + } + + void mark_as_completed() { + get_value() = true; + print_progress(); + } + +private: + template + auto get_value() + -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; + } + + template + auto get_value() const -> decltype( + (details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; + } + + size_t progress_{0}; + Settings settings_; + std::chrono::nanoseconds elapsed_; + std::chrono::time_point start_time_point_; + std::mutex mutex_; + + template friend class MultiProgress; + template friend class DynamicProgress; + std::atomic multi_progress_mode_{false}; + + void save_start_time() { + auto &show_elapsed_time = + get_value(); + auto &saved_start_time = + get_value(); + auto &show_remaining_time = + get_value(); + if ((show_elapsed_time || show_remaining_time) && !saved_start_time) { + start_time_point_ = std::chrono::high_resolution_clock::now(); + saved_start_time = true; + } + } + + std::pair get_prefix_text() { + std::stringstream os; + os << get_value(); + const auto result = os.str(); + const auto result_size = unicode::display_width(result); + return {result, result_size}; + } + + std::pair get_postfix_text() { + std::stringstream os; + const auto max_progress = + get_value(); + + if (get_value()) { + os << " " + << (std::min)(static_cast(static_cast(progress_) / + max_progress * 100), + size_t(100)) + << "%"; + } + + auto &saved_start_time = + get_value(); + + if (get_value()) { + os << " ["; + if (saved_start_time) + details::write_duration(os, elapsed_); + else + os << "00:00s"; + } + + if (get_value()) { + if (get_value()) + os << "<"; + else + os << " ["; + + if (saved_start_time) { + auto eta = std::chrono::nanoseconds( + progress_ > 0 + ? static_cast(std::ceil(float(elapsed_.count()) * + max_progress / progress_)) + : 0); + auto remaining = eta > elapsed_ ? (eta - elapsed_) : (elapsed_ - eta); + details::write_duration(os, remaining); + } else { + os << "00:00s"; + } + + os << "]"; + } else { + if (get_value()) + os << "]"; + } + + os << " " << get_value(); + + const auto result = os.str(); + const auto result_size = unicode::display_width(result); + return {result, result_size}; + } + +public: + void print_progress(bool from_multi_progress = false) { + std::lock_guard lock{mutex_}; + + auto &os = get_value(); + + const auto type = get_value(); + const auto min_progress = + get_value(); + const auto max_progress = + get_value(); + if (multi_progress_mode_ && !from_multi_progress) { + if ((type == ProgressType::incremental && progress_ >= max_progress) || + (type == ProgressType::decremental && progress_ <= min_progress)) { + get_value() = true; + } + return; + } + auto now = std::chrono::high_resolution_clock::now(); + if (!get_value()) + elapsed_ = std::chrono::duration_cast( + now - start_time_point_); + + if (get_value() != + Color::unspecified) + details::set_stream_color( + os, get_value()); + + for (auto &style : get_value()) + details::set_font_style(os, style); + + const auto prefix_pair = get_prefix_text(); + const auto prefix_text = prefix_pair.first; + const auto prefix_length = prefix_pair.second; + os << "\r" << prefix_text; + + os << get_value(); + + details::ProgressScaleWriter writer{ + os, get_value(), + get_value(), + get_value(), + get_value()}; + writer.write(double(progress_) / double(max_progress) * 100.0f); + + os << get_value(); + + const auto postfix_pair = get_postfix_text(); + const auto postfix_text = postfix_pair.first; + const auto postfix_length = postfix_pair.second; + os << postfix_text; + + // Get length of prefix text and postfix text + const auto start_length = get_value().size(); + const auto bar_width = get_value(); + const auto end_length = get_value().size(); + const auto terminal_width = terminal_size().second; + // prefix + bar_width + postfix should be <= terminal_width + const int remaining = terminal_width - (prefix_length + start_length + bar_width + end_length + postfix_length); + if (prefix_length == -1 || postfix_length == -1) { + os << "\r"; + } else if (remaining > 0) { + os << std::string(remaining, ' ') << "\r"; + } else if (remaining < 0) { + // Do nothing. Maybe in the future truncate postfix with ... + } + os.flush(); + + if ((type == ProgressType::incremental && progress_ >= max_progress) || + (type == ProgressType::decremental && progress_ <= min_progress)) { + get_value() = true; + } + if (get_value() && + !from_multi_progress) // Don't std::endl if calling from MultiProgress + os << termcolor::reset << std::endl; + } +}; + +} // namespace indicators + +#endif + + +#ifndef INDICATORS_BLOCK_PROGRESS_BAR +#define INDICATORS_BLOCK_PROGRESS_BAR + +// #include +// #include + +#include +#include +#include +// #include +// #include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace indicators { + +class BlockProgressBar { + using Settings = std::tuple; + +public: + template ::type...>::value, + void *>::type = nullptr> + explicit BlockProgressBar(Args &&... args) + : settings_(details::get( + option::ForegroundColor{Color::unspecified}, std::forward(args)...), + details::get(option::BarWidth{100}, + std::forward(args)...), + details::get(option::Start{"["}, + std::forward(args)...), + details::get(option::End{"]"}, + std::forward(args)...), + details::get( + option::PrefixText{""}, std::forward(args)...), + details::get( + option::PostfixText{""}, std::forward(args)...), + details::get( + option::ShowPercentage{true}, std::forward(args)...), + details::get( + option::ShowElapsedTime{false}, std::forward(args)...), + details::get( + option::ShowRemainingTime{false}, std::forward(args)...), + details::get(option::Completed{false}, + std::forward(args)...), + details::get( + option::SavedStartTime{false}, std::forward(args)...), + details::get( + option::MaxPostfixTextLen{0}, std::forward(args)...), + details::get( + option::FontStyles{std::vector{}}, std::forward(args)...), + details::get( + option::MaxProgress{100}, std::forward(args)...), + details::get(option::Stream{std::cout}, + std::forward(args)...)) {} + + template + void set_option(details::Setting &&setting) { + static_assert(!std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); + std::lock_guard lock(mutex_); + get_value() = std::move(setting).value; + } + + template + void set_option(const details::Setting &setting) { + static_assert(!std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); + std::lock_guard lock(mutex_); + get_value() = setting.value; + } + + void set_option( + const details::Setting &setting) { + std::lock_guard lock(mutex_); + get_value() = setting.value; + if (setting.value.length() > get_value()) { + get_value() = setting.value.length(); + } + } + + void + set_option(details::Setting &&setting) { + std::lock_guard lock(mutex_); + get_value() = std::move(setting).value; + auto &new_value = get_value(); + if (new_value.length() > get_value()) { + get_value() = new_value.length(); + } + } + + void set_progress(float value) { + { + std::lock_guard lock{mutex_}; + progress_ = value; + } + save_start_time(); + print_progress(); + } + + void tick() { + { + std::lock_guard lock{mutex_}; + progress_ += 1; + } + save_start_time(); + print_progress(); + } + + size_t current() { + std::lock_guard lock{mutex_}; + return (std::min)(static_cast(progress_), + size_t(get_value())); + } + + bool is_completed() const { return get_value(); } + + void mark_as_completed() { + get_value() = true; + print_progress(); + } + +private: + template + auto get_value() -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; + } + + template + auto get_value() const + -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; + } + + Settings settings_; + float progress_{0.0}; + std::chrono::time_point start_time_point_; + std::mutex mutex_; + + template friend class MultiProgress; + template friend class DynamicProgress; + std::atomic multi_progress_mode_{false}; + + void save_start_time() { + auto &show_elapsed_time = get_value(); + auto &saved_start_time = get_value(); + auto &show_remaining_time = get_value(); + if ((show_elapsed_time || show_remaining_time) && !saved_start_time) { + start_time_point_ = std::chrono::high_resolution_clock::now(); + saved_start_time = true; + } + } + + std::pair get_prefix_text() { + std::stringstream os; + os << get_value(); + const auto result = os.str(); + const auto result_size = unicode::display_width(result); + return {result, result_size}; + } + + std::pair get_postfix_text() { + std::stringstream os; + const auto max_progress = get_value(); + auto now = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(now - start_time_point_); + + if (get_value()) { + os << " " << (std::min)(static_cast(progress_ / max_progress * 100.0), size_t(100)) + << "%"; + } + + auto &saved_start_time = get_value(); + + if (get_value()) { + os << " ["; + if (saved_start_time) + details::write_duration(os, elapsed); + else + os << "00:00s"; + } + + if (get_value()) { + if (get_value()) + os << "<"; + else + os << " ["; + + if (saved_start_time) { + auto eta = std::chrono::nanoseconds( + progress_ > 0 + ? static_cast(std::ceil(float(elapsed.count()) * + max_progress / progress_)) + : 0); + auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta); + details::write_duration(os, remaining); + } else { + os << "00:00s"; + } + + os << "]"; + } else { + if (get_value()) + os << "]"; + } + + os << " " << get_value(); + + const auto result = os.str(); + const auto result_size = unicode::display_width(result); + return {result, result_size}; + } + +public: + void print_progress(bool from_multi_progress = false) { + std::lock_guard lock{mutex_}; + + auto &os = get_value(); + + const auto max_progress = get_value(); + if (multi_progress_mode_ && !from_multi_progress) { + if (progress_ > max_progress) { + get_value() = true; + } + return; + } + + if (get_value() != Color::unspecified) + details::set_stream_color(os, get_value()); + + for (auto &style : get_value()) + details::set_font_style(os, style); + + const auto prefix_pair = get_prefix_text(); + const auto prefix_text = prefix_pair.first; + const auto prefix_length = prefix_pair.second; + os << "\r" << prefix_text; + + os << get_value(); + + details::BlockProgressScaleWriter writer{os, + get_value()}; + writer.write(progress_ / max_progress * 100); + + os << get_value(); + + const auto postfix_pair = get_postfix_text(); + const auto postfix_text = postfix_pair.first; + const auto postfix_length = postfix_pair.second; + os << postfix_text; + + // Get length of prefix text and postfix text + const auto start_length = get_value().size(); + const auto bar_width = get_value(); + const auto end_length = get_value().size(); + const auto terminal_width = terminal_size().second; + // prefix + bar_width + postfix should be <= terminal_width + const int remaining = terminal_width - (prefix_length + start_length + bar_width + end_length + postfix_length); + if (prefix_length == -1 || postfix_length == -1) { + os << "\r"; + } else if (remaining > 0) { + os << std::string(remaining, ' ') << "\r"; + } else if (remaining < 0) { + // Do nothing. Maybe in the future truncate postfix with ... + } + os.flush(); + + if (progress_ > max_progress) { + get_value() = true; + } + if (get_value() && + !from_multi_progress) // Don't std::endl if calling from MultiProgress + os << termcolor::reset << std::endl; + } +}; + +} // namespace indicators + +#endif + + +#ifndef INDICATORS_INDETERMINATE_PROGRESS_BAR +#define INDICATORS_INDETERMINATE_PROGRESS_BAR + +// #include + +#include +#include +#include +#include +// #include +// #include +// #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace indicators { + +class IndeterminateProgressBar { + using Settings = + std::tuple; + + enum class Direction { forward, backward }; + + Direction direction_{Direction::forward}; + +public: + template ::type...>::value, + void *>::type = nullptr> + explicit IndeterminateProgressBar(Args &&... args) + : settings_(details::get(option::BarWidth{100}, + std::forward(args)...), + details::get( + option::PrefixText{}, std::forward(args)...), + details::get( + option::PostfixText{}, std::forward(args)...), + details::get(option::Start{"["}, + std::forward(args)...), + details::get(option::End{"]"}, + std::forward(args)...), + details::get(option::Fill{"."}, + std::forward(args)...), + details::get(option::Lead{"<==>"}, + std::forward(args)...), + details::get( + option::MaxPostfixTextLen{0}, std::forward(args)...), + details::get(option::Completed{false}, + std::forward(args)...), + details::get( + option::ForegroundColor{Color::unspecified}, std::forward(args)...), + details::get( + option::FontStyles{std::vector{}}, std::forward(args)...), + details::get(option::Stream{std::cout}, + std::forward(args)...)) { + // starts with [<==>...........] + // progress_ = 0 + + // ends with [...........<==>] + // ^^^^^^^^^^^^^^^^^ bar_width + // ^^^^^^^^^^^^ (bar_width - len(lead)) + // progress_ = bar_width - len(lead) + progress_ = 0; + max_progress_ = get_value() - + get_value().size() + + get_value().size() + + get_value().size(); + } + + template + void set_option(details::Setting &&setting) { + static_assert(!std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); + std::lock_guard lock(mutex_); + get_value() = std::move(setting).value; + } + + template + void set_option(const details::Setting &setting) { + static_assert(!std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); + std::lock_guard lock(mutex_); + get_value() = setting.value; + } + + void set_option( + const details::Setting &setting) { + std::lock_guard lock(mutex_); + get_value() = setting.value; + if (setting.value.length() > get_value()) { + get_value() = setting.value.length(); + } + } + + void + set_option(details::Setting &&setting) { + std::lock_guard lock(mutex_); + get_value() = std::move(setting).value; + auto &new_value = get_value(); + if (new_value.length() > get_value()) { + get_value() = new_value.length(); + } + } + + void tick() { + { + std::lock_guard lock{mutex_}; + if (get_value()) + return; + + progress_ += (direction_ == Direction::forward) ? 1 : -1; + if (direction_ == Direction::forward && progress_ == max_progress_) { + // time to go back + direction_ = Direction::backward; + } else if (direction_ == Direction::backward && progress_ == 0) { + direction_ = Direction::forward; + } + } + print_progress(); + } + + bool is_completed() { return get_value(); } + + void mark_as_completed() { + get_value() = true; + print_progress(); + } + +private: + template + auto get_value() -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; + } + + template + auto get_value() const + -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; + } + + size_t progress_{0}; + size_t max_progress_; + Settings settings_; + std::chrono::nanoseconds elapsed_; + std::mutex mutex_; + + template friend class MultiProgress; + template friend class DynamicProgress; + std::atomic multi_progress_mode_{false}; + + std::pair get_prefix_text() { + std::stringstream os; + os << get_value(); + const auto result = os.str(); + const auto result_size = unicode::display_width(result); + return {result, result_size}; + } + + std::pair get_postfix_text() { + std::stringstream os; + os << " " << get_value(); + + const auto result = os.str(); + const auto result_size = unicode::display_width(result); + return {result, result_size}; + } + +public: + void print_progress(bool from_multi_progress = false) { + std::lock_guard lock{mutex_}; + + auto &os = get_value(); + + if (multi_progress_mode_ && !from_multi_progress) { + return; + } + if (get_value() != Color::unspecified) + details::set_stream_color(os, get_value()); + + for (auto &style : get_value()) + details::set_font_style(os, style); + + const auto prefix_pair = get_prefix_text(); + const auto prefix_text = prefix_pair.first; + const auto prefix_length = prefix_pair.second; + os << "\r" << prefix_text; + + os << get_value(); + + details::IndeterminateProgressScaleWriter writer{ + os, get_value(), + get_value(), + get_value()}; + writer.write(progress_); + + os << get_value(); + + const auto postfix_pair = get_postfix_text(); + const auto postfix_text = postfix_pair.first; + const auto postfix_length = postfix_pair.second; + os << postfix_text; + + // Get length of prefix text and postfix text + const auto start_length = get_value().size(); + const auto bar_width = get_value(); + const auto end_length = get_value().size(); + const auto terminal_width = terminal_size().second; + // prefix + bar_width + postfix should be <= terminal_width + const int remaining = terminal_width - (prefix_length + start_length + bar_width + end_length + postfix_length); + if (prefix_length == -1 || postfix_length == -1) { + os << "\r"; + } else if (remaining > 0) { + os << std::string(remaining, ' ') << "\r"; + } else if (remaining < 0) { + // Do nothing. Maybe in the future truncate postfix with ... + } + os.flush(); + + if (get_value() && + !from_multi_progress) // Don't std::endl if calling from MultiProgress + os << termcolor::reset << std::endl; + } +}; + +} // namespace indicators + +#endif + + +#ifndef INDICATORS_MULTI_PROGRESS +#define INDICATORS_MULTI_PROGRESS +#include +#include +#include +#include +#include + +// #include +// #include +// #include + +namespace indicators { + +template class MultiProgress { +public: + template ::type> + explicit MultiProgress(Indicators &... bars) { + bars_ = {bars...}; + for (auto &bar : bars_) { + bar.get().multi_progress_mode_ = true; + } + } + + template + typename std::enable_if<(index >= 0 && index < count), void>::type set_progress(size_t value) { + if (!bars_[index].get().is_completed()) + bars_[index].get().set_progress(value); + print_progress(); + } + + template + typename std::enable_if<(index >= 0 && index < count), void>::type set_progress(float value) { + if (!bars_[index].get().is_completed()) + bars_[index].get().set_progress(value); + print_progress(); + } + + template + typename std::enable_if<(index >= 0 && index < count), void>::type tick() { + if (!bars_[index].get().is_completed()) + bars_[index].get().tick(); + print_progress(); + } + + template + typename std::enable_if<(index >= 0 && index < count), bool>::type is_completed() const { + return bars_[index].get().is_completed(); + } + +private: + std::atomic started_{false}; + std::mutex mutex_; + std::vector> bars_; + + bool _all_completed() { + bool result{true}; + for (size_t i = 0; i < count; ++i) + result &= bars_[i].get().is_completed(); + return result; + } + +public: + void print_progress() { + std::lock_guard lock{mutex_}; + if (started_) + move_up(count); + for (auto &bar : bars_) { + bar.get().print_progress(true); + std::cout << "\n"; + } + std::cout << termcolor::reset; + if (!started_) + started_ = true; + } +}; + +} // namespace indicators + +#endif + + +#ifndef INDICATORS_DYNAMIC_PROGRESS +#define INDICATORS_DYNAMIC_PROGRESS + +#include +#include +// #include +// #include +// #include +// #include +// #include +#include +#include +#include + +namespace indicators { + +template class DynamicProgress { + using Settings = std::tuple; + +public: + template explicit DynamicProgress(Indicators &... bars) { + bars_ = {bars...}; + for (auto &bar : bars_) { + bar.get().multi_progress_mode_ = true; + ++total_count_; + ++incomplete_count_; + } + } + + Indicator &operator[](size_t index) { + print_progress(); + std::lock_guard lock{mutex_}; + return bars_[index].get(); + } + + size_t push_back(Indicator &bar) { + std::lock_guard lock{mutex_}; + bar.multi_progress_mode_ = true; + bars_.push_back(bar); + return bars_.size() - 1; + } + + template + void set_option(details::Setting &&setting) { + static_assert(!std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); + std::lock_guard lock(mutex_); + get_value() = std::move(setting).value; + } + + template + void set_option(const details::Setting &setting) { + static_assert(!std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); + std::lock_guard lock(mutex_); + get_value() = setting.value; + } + +private: + Settings settings_; + std::atomic started_{false}; + std::mutex mutex_; + std::vector> bars_; + std::atomic total_count_{0}; + std::atomic incomplete_count_{0}; + + template + auto get_value() -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; + } + + template + auto get_value() const + -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; + } + +public: + void print_progress() { + std::lock_guard lock{mutex_}; + auto &hide_bar_when_complete = get_value(); + if (hide_bar_when_complete) { + // Hide completed bars + if (started_) { + for (size_t i = 0; i < incomplete_count_; ++i) { + move_up(1); + erase_line(); + std::cout << std::flush; + } + } + incomplete_count_ = 0; + for (auto &bar : bars_) { + if (!bar.get().is_completed()) { + bar.get().print_progress(true); + std::cout << "\n"; + ++incomplete_count_; + } + } + if (!started_) + started_ = true; + } else { + // Don't hide any bars + if (started_) + move_up(static_cast(total_count_)); + for (auto &bar : bars_) { + bar.get().print_progress(true); + std::cout << "\n"; + } + if (!started_) + started_ = true; + } + total_count_ = bars_.size(); + std::cout << termcolor::reset; + } +}; + +} // namespace indicators + +#endif + + +#ifndef INDICATORS_PROGRESS_SPINNER +#define INDICATORS_PROGRESS_SPINNER + +// #include + +#include +#include +#include +#include +// #include +// #include +#include +#include +#include +#include +#include +#include +#include + +namespace indicators { + +class ProgressSpinner { + using Settings = + std::tuple; + +public: + template ::type...>::value, + void *>::type = nullptr> + explicit ProgressSpinner(Args &&... args) + : settings_( + details::get( + option::ForegroundColor{Color::unspecified}, std::forward(args)...), + details::get(option::PrefixText{}, + std::forward(args)...), + details::get(option::PostfixText{}, + std::forward(args)...), + details::get(option::ShowPercentage{true}, + std::forward(args)...), + details::get( + option::ShowElapsedTime{false}, std::forward(args)...), + details::get( + option::ShowRemainingTime{false}, std::forward(args)...), + details::get(option::ShowSpinner{true}, + std::forward(args)...), + details::get( + option::SavedStartTime{false}, std::forward(args)...), + details::get(option::Completed{false}, + std::forward(args)...), + details::get( + option::MaxPostfixTextLen{0}, std::forward(args)...), + details::get( + option::SpinnerStates{ + std::vector{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}}, + std::forward(args)...), + details::get( + option::FontStyles{std::vector{}}, std::forward(args)...), + details::get(option::MaxProgress{100}, + std::forward(args)...), + details::get(option::Stream{std::cout}, + std::forward(args)...)) {} + + template + void set_option(details::Setting &&setting) { + static_assert(!std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); + std::lock_guard lock(mutex_); + get_value() = std::move(setting).value; + } + + template + void set_option(const details::Setting &setting) { + static_assert(!std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); + std::lock_guard lock(mutex_); + get_value() = setting.value; + } + + void set_option( + const details::Setting &setting) { + std::lock_guard lock(mutex_); + get_value() = setting.value; + if (setting.value.length() > get_value()) { + get_value() = setting.value.length(); + } + } + + void + set_option(details::Setting &&setting) { + std::lock_guard lock(mutex_); + get_value() = std::move(setting).value; + auto &new_value = get_value(); + if (new_value.length() > get_value()) { + get_value() = new_value.length(); + } + } + + void set_progress(size_t value) { + { + std::lock_guard lock{mutex_}; + progress_ = value; + } + save_start_time(); + print_progress(); + } + + void tick() { + { + std::lock_guard lock{mutex_}; + progress_ += 1; + } + save_start_time(); + print_progress(); + } + + size_t current() { + std::lock_guard lock{mutex_}; + return (std::min)(progress_, size_t(get_value())); + } + + bool is_completed() const { return get_value(); } + + void mark_as_completed() { + get_value() = true; + print_progress(); + } + +private: + Settings settings_; + size_t progress_{0}; + size_t index_{0}; + std::chrono::time_point start_time_point_; + std::mutex mutex_; + + template + auto get_value() -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; + } + + template + auto get_value() const + -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; + } + + void save_start_time() { + auto &show_elapsed_time = get_value(); + auto &show_remaining_time = get_value(); + auto &saved_start_time = get_value(); + if ((show_elapsed_time || show_remaining_time) && !saved_start_time) { + start_time_point_ = std::chrono::high_resolution_clock::now(); + saved_start_time = true; + } + } + +public: + void print_progress() { + std::lock_guard lock{mutex_}; + + auto &os = get_value(); + + const auto max_progress = get_value(); + auto now = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(now - start_time_point_); + + if (get_value() != Color::unspecified) + details::set_stream_color(os, get_value()); + + for (auto &style : get_value()) + details::set_font_style(os, style); + + os << get_value(); + if (get_value()) + os << get_value() + [index_ % get_value().size()]; + if (get_value()) { + os << " " << std::size_t(progress_ / double(max_progress) * 100) << "%"; + } + + if (get_value()) { + os << " ["; + details::write_duration(os, elapsed); + } + + if (get_value()) { + if (get_value()) + os << "<"; + else + os << " ["; + auto eta = std::chrono::nanoseconds( + progress_ > 0 + ? static_cast(std::ceil(float(elapsed.count()) * + max_progress / progress_)) + : 0); + auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta); + details::write_duration(os, remaining); + os << "]"; + } else { + if (get_value()) + os << "]"; + } + + if (get_value() == 0) + get_value() = 10; + os << " " << get_value() + << std::string(get_value(), ' ') << "\r"; + os.flush(); + index_ += 1; + if (progress_ > max_progress) { + get_value() = true; + } + if (get_value()) + os << termcolor::reset << std::endl; + } +}; + +} // namespace indicators + +#endif + diff --git a/Sofa/GUI/Common/CMakeLists.txt b/Sofa/GUI/Common/CMakeLists.txt index 2a07888178a1..0da109387ced 100644 --- a/Sofa/GUI/Common/CMakeLists.txt +++ b/Sofa/GUI/Common/CMakeLists.txt @@ -4,7 +4,7 @@ project(Sofa.GUI.Common LANGUAGES CXX) include(FetchContent) FetchContent_Declare(cxxopts GIT_REPOSITORY https://github.com/jarro2783/cxxopts - GIT_TAG v2.2.1 + GIT_TAG v3.1.1 ) FetchContent_GetProperties(cxxopts) diff --git a/Sofa/GUI/Common/src/sofa/gui/common/ArgumentParser.cpp b/Sofa/GUI/Common/src/sofa/gui/common/ArgumentParser.cpp index fc005e1a0881..b66f93d6e5bc 100644 --- a/Sofa/GUI/Common/src/sofa/gui/common/ArgumentParser.cpp +++ b/Sofa/GUI/Common/src/sofa/gui/common/ArgumentParser.cpp @@ -85,7 +85,7 @@ void ArgumentParser::parse() const auto temp = m_options.parse(copyArgc, copyArgv); vecArg = temp.arguments(); } - catch (const cxxopts::OptionException& e) + catch (const cxxopts::exceptions::exception& e) { msg_error("ArgumentParser") << e.what(); exit(EXIT_FAILURE); diff --git a/Sofa/GUI/Common/src/sofa/gui/common/ArgumentParser.h b/Sofa/GUI/Common/src/sofa/gui/common/ArgumentParser.h index 0b2bc0b7b348..60eb31a23379 100644 --- a/Sofa/GUI/Common/src/sofa/gui/common/ArgumentParser.h +++ b/Sofa/GUI/Common/src/sofa/gui/common/ArgumentParser.h @@ -114,7 +114,7 @@ class SOFA_GUI_COMMON_API ArgumentParser SOFA_UNUSED(e1); ret = false; } - catch (const cxxopts::OptionParseException& e2) // option is not present, etc + catch (const cxxopts::exceptions::exception& e2) // option is not present, etc { SOFA_UNUSED(e2); ret = false; From 9513c53018f9239bd3641a9b243f4cab2959831d Mon Sep 17 00:00:00 2001 From: erik pernod Date: Thu, 5 Oct 2023 13:32:02 +0200 Subject: [PATCH 12/60] [Topology.Container] Update and rename methods in EdgeSetGeometryAlgorithms to compute barycentric coordinates (#4190) * [Topology] Redirect method in EdgeSetTopologyContainer to the geometry Edge pointBarycoefs method * [EdgeSetTopology] Rename method compute2PointsBarycoefs into computeEdgeBarycentricCoordinates * [EdgeSetTopology] update computeEdgeBarycentricCoordinates signature and merge the rest and current position methods * [EdgeSetTopology] Add deprecated process to compute2PointsBarycoefs * [EdgeSetTopology] revert signature and add doc * [Topology] propagate use of new method * Fix bad cherry pick * Fix bad cherry pick * remove method compute_2points_barycoefs --------- Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --- .../dynamic/EdgeSetGeometryAlgorithms.h | 23 +++- .../dynamic/EdgeSetGeometryAlgorithms.inl | 121 ++++-------------- .../TetrahedronSetGeometryAlgorithms.inl | 4 +- .../dynamic/TriangleSetGeometryAlgorithms.inl | 2 +- 4 files changed, 46 insertions(+), 104 deletions(-) diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h index 46a3520af440..8ae84f6bdc44 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h @@ -81,8 +81,6 @@ class EdgeSetGeometryAlgorithms : public PointSetGeometryAlgorithms void defineEdgeCubaturePoints(); public: - //virtual void reinit(); - void draw(const core::visual::VisualParams* vparams) override; /// computes the length of edge no i and returns it @@ -111,9 +109,15 @@ class EdgeSetGeometryAlgorithms : public PointSetGeometryAlgorithms // test if a point is on the triangle indexed by ind_e bool isPointOnEdge(const sofa::type::Vec<3, Real> &pt, const EdgeID ind_e) const; - // compute barycentric coefficients - sofa::type::vector< SReal > compute2PointsBarycoefs(const sofa::type::Vec<3, Real> &p, PointID ind_p1, PointID ind_p2) const; - sofa::type::vector< SReal > computeRest2PointsBarycoefs(const sofa::type::Vec<3, Real> &p, PointID ind_p1, PointID ind_p2) const; + + /** \brief Compute the barycentric coordinates of input point p between edge of indices [ind_p1; ind_p2] using either current position or restPosition depending on useRestPosition value. + * @param p position of the point to compute the coefficients. + * @param ind_p1 PointID of first vertex to be used to compute the barycentric coordinates of input point. + * @param ind_p2 PointID of second vertex to be used to compute the barycentric coordinates of input point. + * @param useRestPosition bool false to use position, true to use rest_position. + * @return the 2 barycentric coordinates inside a vector. + */ + sofa::type::vector< SReal > computeEdgeBarycentricCoordinates(const sofa::type::Vec<3, Real> &p, PointID ind_p1, PointID ind_p2, bool useRestPosition = false) const; /** \brief Compute the projection coordinate of a point C on the edge i. Using compute2EdgesIntersection(). * @param i edgeID on which point is projected. @@ -161,8 +165,17 @@ class EdgeSetGeometryAlgorithms : public PointSetGeometryAlgorithms const sofa::type::Vec<3, Real>& b, Real &baryCoef); + + // compute barycentric coefficients + SOFA_ATTRIBUTE_DEPRECATED("v23.12", "v24.06", "Use sofa::component::topology::container::dynamic::EdgeSetGeometryAlgorithms::computeEdgeBarycentricCoordinates") + sofa::type::vector< SReal > compute2PointsBarycoefs(const sofa::type::Vec<3, Real> &p, PointID ind_p1, PointID ind_p2) const; + + SOFA_ATTRIBUTE_DEPRECATED("v23.12", "v24.06", "Use sofa::component::topology::container::dynamic::EdgeSetGeometryAlgorithms::computeEdgeBarycentricCoordinates with useRestPosition = true") + sofa::type::vector< SReal > computeRest2PointsBarycoefs(const sofa::type::Vec<3, Real> &p, PointID ind_p1, PointID ind_p2) const; + SOFA_ATTRIBUTE_DISABLED("v23.12", "v23.12", "Method writeMSHfile has been disabled. To export the topology as .gmsh file, use the sofa::component::io::mesh::MeshExporter.") void writeMSHfile(const char *filename) const {msg_deprecated() << "Method writeMSHfile has been disabled. To export the topology as " << filename << " file, use the sofa::component::io::mesh::MeshExporter."; } + protected: Data showEdgeIndices; ///< Debug : view Edge indices. Data d_drawEdges; ///< if true, draw the edges in the topology. diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.inl b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.inl index 5b2f8369e253..d98eb27f6084 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.inl +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.inl @@ -361,44 +361,28 @@ bool EdgeSetGeometryAlgorithms::isPointOnEdge(const sofa::type::Vec<3 return sofa::geometry::Edge::isPointOnEdge(pt, p1, p2); } -// + template -auto EdgeSetGeometryAlgorithms::compute2PointsBarycoefs( +auto EdgeSetGeometryAlgorithms::computeEdgeBarycentricCoordinates( const sofa::type::Vec<3, Real> &p, - PointID ind_p1, - PointID ind_p2) const -> sofa::type::vector< SReal > + PointID ind_p1, PointID ind_p2, bool useRestPosition) const -> sofa::type::vector< SReal > { - constexpr Real ZERO = static_cast(1e-6); - - sofa::type::vector< SReal > baryCoefs; + sofa::core::ConstVecCoordId::MyVecId _vecId = useRestPosition ? core::ConstVecCoordId::restPosition() : core::ConstVecCoordId::position(); - const typename DataTypes::VecCoord& vect_c =(this->object->read(core::ConstVecCoordId::position())->getValue()); + const typename DataTypes::VecCoord& vect_c = (this->object->read(_vecId)->getValue()); const typename DataTypes::Coord& c0 = vect_c[ind_p1]; const typename DataTypes::Coord& c1 = vect_c[ind_p2]; sofa::type::Vec<3, Real> a; DataTypes::get(a[0], a[1], a[2], c0); sofa::type::Vec<3, Real> b; DataTypes::get(b[0], b[1], b[2], c1); - Real dis = (b - a).norm(); - Real coef_a, coef_b; - - - if(dis < ZERO) - { - coef_a = 0.5; - coef_b = 0.5; - } - else - { - coef_a = (p - b).norm() / dis; - coef_b = (p - a).norm() / dis; - } + sofa::type::Vec<2, Real> coefs = sofa::geometry::Edge::getBarycentricCoordinates(p, a, b); + sofa::type::vector< SReal > baryCoefs; - baryCoefs.push_back(coef_a); - baryCoefs.push_back(coef_b); + baryCoefs.push_back(coefs[0]); + baryCoefs.push_back(coefs[1]); return baryCoefs; - } @@ -414,74 +398,6 @@ bool is_point_on_edge(const Vec& p, const Vec& a, const Vec& b) return false; } -template -auto EdgeSetGeometryAlgorithms::computeRest2PointsBarycoefs( - const sofa::type::Vec<3, Real>& p, - PointID ind_p1, - PointID ind_p2) const -> sofa::type::vector -{ - constexpr Real ZERO = static_cast(1e-6); - - sofa::type::vector< SReal > baryCoefs; - - const typename DataTypes::VecCoord& vect_c = (this->object->read(core::ConstVecCoordId::restPosition())->getValue()); - const typename DataTypes::Coord& c0 = vect_c[ind_p1]; - const typename DataTypes::Coord& c1 = vect_c[ind_p2]; - - sofa::type::Vec<3,Real> a; DataTypes::get(a[0], a[1], a[2], c0); - sofa::type::Vec<3,Real> b; DataTypes::get(b[0], b[1], b[2], c1); - - Real dis = (b - a).norm(); - Real coef_a, coef_b; - - - if(dis < ZERO) - { - coef_a = 0.5; - coef_b = 0.5; - } - else - { - coef_a = (p - b).norm() / dis; - coef_b = (p - a).norm() / dis; - } - - baryCoefs.push_back(coef_a); - baryCoefs.push_back(coef_b); - - return baryCoefs; - -} - -template -sofa::type::vector< typename Vec::value_type > compute_2points_barycoefs(const Vec& p, const Vec& a, const Vec& b) -{ - using Real = typename Vec::value_type; - const Real ZERO = 1e-6; - - sofa::type::vector< Real > baryCoefs; - - Real dis = (b - a).norm(); - Real coef_a, coef_b; - - if(dis < ZERO) - { - coef_a = 0.5; - coef_b = 0.5; - } - else - { - coef_a = (p - b).norm() / dis; - coef_b = (p - a).norm() / dis; - } - - baryCoefs.push_back(coef_a); - baryCoefs.push_back(coef_b); - - return baryCoefs; -} - - template auto EdgeSetGeometryAlgorithms::computePointProjectionOnEdge (const EdgeID edgeIndex, sofa::type::Vec<3, Real> c, @@ -524,9 +440,7 @@ auto EdgeSetGeometryAlgorithms::computePointProjectionOnEdge (const E Coord coord_H = compute2EdgesIntersection ( coord_edge1, coord_edge2, intersected); sofa::type::Vec<3, Real> h; DataTypes::get(h[0], h[1], h[2], coord_H); - auto barycoord = compute2PointsBarycoefs(h, theEdge[0], theEdge[1]); - return barycoord; - + return computeEdgeBarycentricCoordinates(h, theEdge[0], theEdge[1]); } template @@ -903,4 +817,19 @@ bool EdgeSetGeometryAlgorithms::mustComputeBBox() const return ( (this->m_topology->getNbEdges() != 0 && (d_drawEdges.getValue() || showEdgeIndices.getValue())) || Inherit1::mustComputeBBox() ); } + +template +sofa::type::vector< SReal > EdgeSetGeometryAlgorithms::compute2PointsBarycoefs(const sofa::type::Vec<3, Real> &p, PointID ind_p1, PointID ind_p2) const +{ + return computeEdgeBarycentricCoordinates(p, ind_p1, ind_p2); +} + + +template +sofa::type::vector< SReal > EdgeSetGeometryAlgorithms::computeRest2PointsBarycoefs(const sofa::type::Vec<3, Real> &p, PointID ind_p1, PointID ind_p2) const +{ + return computeEdgeBarycentricCoordinates(p, ind_p1, ind_p2, true); +} + + } //namespace sofa::component::topology::container::dynamic diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetGeometryAlgorithms.inl b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetGeometryAlgorithms.inl index e15d1ca0bc8b..a84049e4688c 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetGeometryAlgorithms.inl +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TetrahedronSetGeometryAlgorithms.inl @@ -1132,7 +1132,7 @@ void TetrahedronSetGeometryAlgorithms::subDivideTetrahedronsWithPlane Edge theEdge=m_container->getEdge(intersectedEdgeID[i]); sofa::type::Vec<3,Real> p; p[0]=intersectedPoints[i][0]; p[1]=intersectedPoints[i][1]; p[2]=intersectedPoints[i][2]; - sofa::type::vector< SReal > coef = this->compute2PointsBarycoefs(p, theEdge[0], theEdge[1]); + sofa::type::vector< SReal > coef = this->computeEdgeBarycentricCoordinates(p, theEdge[0], theEdge[1]); sofa::type::vector< EdgeID > ancestor; ancestor.push_back(theEdge[0]); ancestor.push_back(theEdge[1]); @@ -2243,7 +2243,7 @@ void TetrahedronSetGeometryAlgorithms::subDivideRestTetrahedronsWithP Edge theEdge=m_container->getEdge(intersectedEdgeID[i]); sofa::type::Vec<3,Real> p; p[0]=intersectedPoints[i][0]; p[1]=intersectedPoints[i][1]; p[2]=intersectedPoints[i][2]; - sofa::type::vector< SReal > coef = this->computeRest2PointsBarycoefs(p, theEdge[0], theEdge[1]); + sofa::type::vector< SReal > coef = this->computeEdgeBarycentricCoordinates(p, theEdge[0], theEdge[1], true); sofa::type::vector< EdgeID > ancestor; ancestor.push_back(theEdge[0]); ancestor.push_back(theEdge[1]); diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl index 1238347a6f76..2061c94a1a1a 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.inl @@ -4088,7 +4088,7 @@ int TriangleSetGeometryAlgorithms::SplitAlongPath(PointID pa, Coord& ancestors2Snap[i].push_back((PointID)points2Snap[i][6]); } else - coefs2Snap[i] = this->compute2PointsBarycoefs(SnapedCoord, firstAncestor, secondAncestor); + coefs2Snap[i] = this->computeEdgeBarycentricCoordinates(SnapedCoord, firstAncestor, secondAncestor); } m_modifier->movePointsProcess(id2Snap, ancestors2Snap, coefs2Snap); } From be8797bc5d6c45868b68596041aa78cdefa1bda5 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 5 Oct 2023 15:13:14 +0200 Subject: [PATCH 13/60] [all] Fix mismatch on explicit template instantiations (#4210) --- .../detection/intersection/DiscreteIntersection.h | 2 +- .../detection/intersection/MinProximityIntersection.h | 2 +- .../detection/intersection/NewProximityIntersection.h | 2 +- .../sofa/component/collision/geometry/TriangleModel.h | 2 +- .../response/contact/PenalityContactForceField.h | 2 +- .../collision/response/mapper/IdentityContactMapper.h | 2 +- .../collision/response/mapper/RigidContactMapper.h | 2 +- .../mapper/TetrahedronBarycentricContactMapper.h | 2 +- .../correction/LinearSolverConstraintCorrection.h | 2 +- .../correction/PrecomputedConstraintCorrection.h | 2 +- .../correction/UncoupledConstraintCorrection.h | 2 +- .../constraint/lagrangian/model/SlidingConstraint.h | 2 +- .../constraint/lagrangian/model/StopperConstraint.h | 2 +- .../lagrangian/model/UnilateralInteractionConstraint.h | 2 +- .../constraint/projective/AffineMovementConstraint.cpp | 2 +- .../constraint/projective/AffineMovementConstraint.h | 5 ++--- .../component/constraint/projective/AttachConstraint.h | 2 +- .../component/constraint/projective/FixedConstraint.h | 2 +- .../constraint/projective/FixedRotationConstraint.h | 2 +- .../constraint/projective/FixedTranslationConstraint.h | 2 +- .../constraint/projective/LinearMovementConstraint.h | 2 +- .../constraint/projective/LinearVelocityConstraint.h | 2 +- .../constraint/projective/OscillatorConstraint.h | 2 +- .../constraint/projective/ParabolicConstraint.h | 2 +- .../constraint/projective/PartialFixedConstraint.h | 2 +- .../projective/PartialLinearMovementConstraint.h | 2 +- .../constraint/projective/PatchTestMovementConstraint.h | 2 +- .../projective/PositionBasedDynamicsConstraint.h | 2 +- .../constraint/projective/ProjectDirectionConstraint.h | 2 +- .../constraint/projective/ProjectToLineConstraint.h | 2 +- .../constraint/projective/ProjectToPlaneConstraint.h | 2 +- .../constraint/projective/ProjectToPointConstraint.h | 2 +- .../component/controller/MechanicalStateController.h | 2 +- .../diffusion/TetrahedronDiffusionFEMForceField.h | 2 +- .../src/sofa/component/engine/analyze/AverageCoord.h | 2 +- .../src/sofa/component/engine/analyze/ClusteringEngine.h | 2 +- .../src/sofa/component/engine/analyze/Distances.h | 2 +- .../sofa/component/engine/analyze/HausdorffDistance.h | 2 +- .../src/sofa/component/engine/analyze/ShapeMatching.h | 2 +- .../src/sofa/component/engine/analyze/SumEngine.h | 2 +- .../engine/generate/ExtrudeEdgesAndGenerateQuads.h | 2 +- .../engine/generate/ExtrudeQuadsAndGenerateHexas.h | 2 +- .../src/sofa/component/engine/generate/ExtrudeSurface.h | 2 +- .../sofa/component/engine/generate/GenerateCylinder.h | 2 +- .../src/sofa/component/engine/generate/GenerateGrid.h | 2 +- .../sofa/component/engine/generate/GenerateRigidMass.h | 2 +- .../src/sofa/component/engine/generate/GenerateSphere.h | 2 +- .../component/engine/generate/GroupFilterYoungModulus.h | 2 +- .../src/sofa/component/engine/generate/JoinPoints.h | 2 +- .../src/sofa/component/engine/generate/MergeMeshes.h | 2 +- .../src/sofa/component/engine/generate/MergePoints.h | 2 +- .../src/sofa/component/engine/generate/MergeSets.h | 2 +- .../src/sofa/component/engine/generate/MergeVectors.h | 2 +- .../engine/generate/MeshBarycentricMapperEngine.h | 2 +- .../sofa/component/engine/generate/MeshClosingEngine.h | 2 +- .../src/sofa/component/engine/generate/NormEngine.h | 2 +- .../sofa/component/engine/generate/NormalsFromPoints.h | 2 +- .../engine/generate/RandomPointDistributionInSurface.h | 2 +- .../Generate/src/sofa/component/engine/generate/Spiral.h | 2 +- .../Select/src/sofa/component/engine/select/BoxROI.h | 2 +- .../src/sofa/component/engine/select/ComplementaryROI.h | 2 +- .../src/sofa/component/engine/select/IndicesFromValues.h | 2 +- .../Select/src/sofa/component/engine/select/MeshROI.h | 5 ++--- .../src/sofa/component/engine/select/MeshSampler.h | 2 +- .../sofa/component/engine/select/MeshSplittingEngine.h | 2 +- .../src/sofa/component/engine/select/MeshSubsetEngine.h | 2 +- .../src/sofa/component/engine/select/NearestPointROI.h | 2 +- .../Select/src/sofa/component/engine/select/PairBoxRoi.h | 2 +- .../Select/src/sofa/component/engine/select/PlaneROI.h | 2 +- .../src/sofa/component/engine/select/PointsFromIndices.h | 2 +- .../src/sofa/component/engine/select/ProximityROI.h | 2 +- .../Select/src/sofa/component/engine/select/SphereROI.h | 2 +- .../src/sofa/component/engine/select/SubsetTopology.h | 2 +- .../src/sofa/component/engine/select/ValuesFromIndices.h | 2 +- .../sofa/component/engine/select/ValuesFromPositions.h | 2 +- .../sofa/component/engine/transform/DifferenceEngine.h | 2 +- .../src/sofa/component/engine/transform/DilateEngine.cpp | 1 + .../src/sofa/component/engine/transform/DilateEngine.h | 2 +- .../sofa/component/engine/transform/IndexValueMapper.h | 2 +- .../component/engine/transform/Indices2ValuesMapper.h | 2 +- .../src/sofa/component/engine/transform/MapIndices.h | 2 +- .../src/sofa/component/engine/transform/MathOp.h | 2 +- .../engine/transform/ProjectiveTransformEngine.h | 2 +- .../sofa/component/engine/transform/QuatToRigidEngine.h | 2 +- .../sofa/component/engine/transform/RigidToQuatEngine.h | 2 +- .../sofa/component/engine/transform/SmoothMeshEngine.h | 2 +- .../sofa/component/engine/transform/TransformEngine.h | 2 +- .../sofa/component/engine/transform/TransformPosition.h | 2 +- .../src/sofa/component/engine/transform/Vertex2Frame.h | 2 +- .../src/sofa/component/haptics/LCPForceFeedback.h | 2 +- .../component/linearsolver/direct/AsyncSparseLDLSolver.h | 2 +- .../sofa/component/linearsolver/direct/BTDLinearSolver.h | 2 +- .../sofa/component/linearsolver/direct/CholeskySolver.h | 2 +- .../component/linearsolver/direct/SparseCholeskySolver.h | 2 +- .../sofa/component/linearsolver/direct/SparseLDLSolver.h | 2 +- .../sofa/component/linearsolver/direct/SparseLUSolver.h | 2 +- .../component/linearsolver/iterative/CGLinearSolver.h | 2 +- .../component/mapping/linear/BarycentricMappingRigid.h | 2 +- .../sofa/component/mapping/linear/BeamLinearMapping.h | 4 ++-- .../component/mapping/linear/CenterOfMassMapping.cpp | 1 + .../sofa/component/mapping/linear/CenterOfMassMapping.h | 2 +- .../component/mapping/linear/CenterOfMassMulti2Mapping.h | 2 +- .../component/mapping/linear/CenterOfMassMultiMapping.h | 2 +- .../mapping/linear/DeformableOnRigidFrameMapping.h | 2 +- .../src/sofa/component/mapping/linear/IdentityMapping.h | 2 +- .../sofa/component/mapping/linear/IdentityMultiMapping.h | 2 +- .../component/mapping/linear/LineSetSkinningMapping.h | 2 +- .../mapping/linear/Mesh2PointMechanicalMapping.h | 2 +- .../linear/SimpleTesselatedTetraMechanicalMapping.h | 2 +- .../src/sofa/component/mapping/linear/SkinningMapping.h | 2 +- .../src/sofa/component/mapping/linear/SubsetMapping.h | 2 +- .../sofa/component/mapping/linear/SubsetMultiMapping.h | 2 +- .../src/sofa/component/mapping/linear/TubularMapping.h | 2 +- .../mapping/nonlinear/DistanceFromTargetMapping.h | 2 +- .../sofa/component/mapping/nonlinear/DistanceMapping.h | 2 +- .../component/mapping/nonlinear/DistanceMultiMapping.h | 2 +- .../src/sofa/component/mapping/nonlinear/RigidMapping.h | 2 +- .../component/mapping/nonlinear/SquareDistanceMapping.h | 2 +- .../src/sofa/component/mapping/nonlinear/SquareMapping.h | 2 +- .../Mass/src/sofa/component/mass/DiagonalMass.h | 2 +- .../Mass/src/sofa/component/mass/MeshMatrixMass.h | 2 +- .../sofa/component/mechanicalload/ConicalForceField.h | 2 +- .../mechanicalload/DiagonalVelocityDampingForceField.h | 2 +- .../component/mechanicalload/EdgePressureForceField.h | 2 +- .../sofa/component/mechanicalload/EllipsoidForceField.h | 2 +- .../mechanicalload/InteractionEllipsoidForceField.h | 2 +- .../src/sofa/component/mechanicalload/LinearForceField.h | 2 +- .../OscillatingTorsionPressureForceField.h | 2 +- .../src/sofa/component/mechanicalload/PlaneForceField.h | 2 +- .../component/mechanicalload/QuadPressureForceField.h | 2 +- .../src/sofa/component/mechanicalload/SphereForceField.h | 2 +- .../component/mechanicalload/SurfacePressureForceField.h | 2 +- .../mechanicalload/TaitSurfacePressureForceField.h | 2 +- .../sofa/component/mechanicalload/TorsionForceField.h | 2 +- .../mechanicalload/UniformVelocityDampingForceField.h | 2 +- .../solidmechanics/fem/elastic/BeamFEMForceField.h | 2 +- .../fem/elastic/FastTetrahedralCorotationalForceField.h | 2 +- .../solidmechanics/fem/elastic/HexahedralFEMForceField.h | 2 +- .../fem/elastic/HexahedralFEMForceFieldAndMass.h | 2 +- .../solidmechanics/fem/elastic/HexahedronFEMForceField.h | 2 +- .../fem/elastic/HexahedronFEMForceFieldAndMass.h | 2 +- .../fem/elastic/QuadBendingFEMForceField.h | 2 +- .../fem/elastic/TetrahedralCorotationalFEMForceField.h | 2 +- .../solidmechanics/fem/elastic/TriangleFEMForceField.h | 2 +- .../fem/elastic/TriangularAnisotropicFEMForceField.h | 2 +- .../solidmechanics/fem/elastic/TriangularFEMForceField.h | 2 +- .../fem/elastic/TriangularFEMForceFieldOptim.h | 2 +- .../fem/hyperelastic/StandardTetrahedralFEMForceField.h | 2 +- .../TetrahedronHyperelasticityFEMForceField.h | 2 +- .../nonuniform/HexahedronCompositeFEMForceFieldAndMass.h | 2 +- .../fem/nonuniform/HexahedronCompositeFEMMapping.h | 2 +- .../NonUniformHexahedralFEMForceFieldAndMass.h | 2 +- .../NonUniformHexahedronFEMForceFieldAndMass.h | 2 +- .../solidmechanics/spring/AngularSpringForceField.h | 2 +- .../solidmechanics/spring/FastTriangularBendingSprings.h | 2 +- .../solidmechanics/spring/FrameSpringForceField.h | 2 +- .../solidmechanics/spring/GearSpringForceField.h | 2 +- .../sofa/component/solidmechanics/spring/JointSpring.h | 2 +- .../solidmechanics/spring/MeshSpringForceField.h | 2 +- .../component/solidmechanics/spring/QuadBendingSprings.h | 2 +- .../solidmechanics/spring/QuadularBendingSprings.h | 2 +- .../solidmechanics/spring/RegularGridSpringForceField.h | 2 +- .../solidmechanics/spring/RepulsiveSpringForceField.h | 2 +- .../solidmechanics/spring/RestShapeSpringsForceField.h | 2 +- .../component/solidmechanics/spring/SpringForceField.h | 2 +- .../solidmechanics/spring/TriangleBendingSprings.h | 2 +- .../solidmechanics/spring/TriangularBendingSprings.h | 2 +- .../spring/TriangularBiquadraticSpringsForceField.h | 2 +- .../spring/TriangularQuadraticSpringsForceField.h | 2 +- .../solidmechanics/spring/VectorSpringForceField.h | 2 +- .../tensormass/TetrahedralTensorMassForceField.h | 2 +- .../tensormass/TriangularTensorMassForceField.h | 2 +- .../src/sofa/component/statecontainer/MappedObject.h | 2 +- .../src/sofa/component/statecontainer/MechanicalObject.h | 2 +- .../dynamic/DynamicSparseGridGeometryAlgorithms.h | 2 +- .../container/dynamic/EdgeSetGeometryAlgorithms.h | 2 +- .../container/dynamic/HexahedronSetGeometryAlgorithms.h | 2 +- .../container/dynamic/NumericalIntegrationDescriptor.h | 2 +- .../container/dynamic/PointSetGeometryAlgorithms.h | 2 +- .../container/dynamic/QuadSetGeometryAlgorithms.h | 2 +- .../container/dynamic/TriangleSetGeometryAlgorithms.h | 2 +- .../component/topology/utility/TopologyBoundingTrasher.h | 2 +- .../src/sofa/gl/component/engine/TextureInterpolation.h | 2 +- Sofa/GL/src/sofa/gl/BasicShapesGL.h | 2 +- .../sofa/gui/component/performer/AttachBodyPerformer.h | 2 +- .../gui/component/performer/ComponentMouseInteraction.h | 4 ++-- .../component/performer/ConstraintAttachBodyPerformer.h | 2 +- .../sofa/gui/component/performer/FixParticlePerformer.h | 2 +- .../src/sofa/gui/component/performer/MouseInteractor.h | 2 +- .../gui/component/performer/RemovePrimitivePerformer.h | 2 +- .../sofa/gui/component/performer/SuturePointPerformer.h | 2 +- Sofa/GUI/Qt/src/sofa/gui/qt/DataWidget.h | 2 +- Sofa/framework/Core/src/sofa/core/Multi2Mapping.h | 2 +- Sofa/framework/Core/src/sofa/core/State.h | 2 +- Sofa/framework/Core/src/sofa/core/behavior/Constraint.h | 4 ++-- .../Core/src/sofa/core/behavior/ConstraintCorrection.h | 4 ++-- Sofa/framework/Core/src/sofa/core/behavior/ForceField.h | 2 +- Sofa/framework/Core/src/sofa/core/behavior/Mass.h | 2 +- .../Core/src/sofa/core/behavior/MechanicalState.h | 2 +- .../src/sofa/core/behavior/MixedInteractionConstraint.h | 2 +- .../src/sofa/core/behavior/MixedInteractionForceField.h | 4 ++-- .../src/sofa/core/behavior/PairInteractionConstraint.h | 2 +- .../src/sofa/core/behavior/PairInteractionForceField.h | 2 +- .../behavior/PairInteractionProjectiveConstraintSet.h | 2 +- .../src/sofa/core/behavior/ProjectiveConstraintSet.h | 4 ++-- Sofa/framework/Core/src/sofa/core/objectmodel/Data.h | 2 +- Sofa/framework/Helper/src/sofa/helper/AdvancedTimer.h | 2 +- Sofa/framework/Helper/src/sofa/helper/Polynomial_LD.h | 2 +- Sofa/framework/Helper/src/sofa/helper/decompose.h | 2 +- Sofa/framework/Helper/src/sofa/helper/io/Image.h | 2 +- Sofa/framework/Helper/src/sofa/helper/kdTree.h | 2 +- .../framework/Helper/test/system/TestPlugin/ComponentB.h | 2 +- .../Common/src/sofa/simulation/common/xml/BaseElement.h | 2 +- .../ArticulatedSystemPlugin/ArticulatedSystemMapping.h | 2 +- .../plugins/SofaCUDA/sofa/gpu/cuda/CudaBaseVector.h | 2 +- .../component/statecontainer/CudaMechanicalObject.h | 9 +++++++++ .../SofaMatrix/src/SofaMatrix/FillReducingOrdering.h | 2 +- 217 files changed, 233 insertions(+), 224 deletions(-) diff --git a/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/DiscreteIntersection.h b/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/DiscreteIntersection.h index 2f4bae5dc5da..c39dcce3900f 100644 --- a/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/DiscreteIntersection.h +++ b/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/DiscreteIntersection.h @@ -98,7 +98,7 @@ class SOFA_COMPONENT_COLLISION_DETECTION_INTERSECTION_API DiscreteIntersection : namespace sofa::core::collision { -#if !defined(SOFA_COMPONENT_COLLISION_DISCRETEINTERSECTION_CPP) +#if !defined(SOFA_COMPONENT_COLLISION_DISCRETEINTERSECTION_CPP) extern template class SOFA_COMPONENT_COLLISION_DETECTION_INTERSECTION_API IntersectorFactory; #endif } // namespace sofa::core::collision diff --git a/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/MinProximityIntersection.h b/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/MinProximityIntersection.h index 3aaf3b5513cf..cc4272ec2b71 100644 --- a/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/MinProximityIntersection.h +++ b/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/MinProximityIntersection.h @@ -92,7 +92,7 @@ class SOFA_COMPONENT_COLLISION_DETECTION_INTERSECTION_API MinProximityIntersecti namespace sofa::core::collision { -#if !defined(SOFA_COMPONENT_COLLISION_MINPROXIMITYINTERSECTION_CPP) +#if !defined(SOFA_COMPONENT_COLLISION_MINPROXIMITYINTERSECTION_CPP) extern template class SOFA_COMPONENT_COLLISION_DETECTION_INTERSECTION_API IntersectorFactory; #endif } // namespace sofa::core::collision diff --git a/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/NewProximityIntersection.h b/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/NewProximityIntersection.h index 06c2586b3624..ad29aceb3e2c 100644 --- a/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/NewProximityIntersection.h +++ b/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/NewProximityIntersection.h @@ -83,7 +83,7 @@ class SOFA_COMPONENT_COLLISION_DETECTION_INTERSECTION_API NewProximityIntersecti namespace sofa::core::collision { -#if !defined(SOFA_COMPONENT_COLLISION_NEWPROXIMITYINTERSECTION_CPP) +#if !defined(SOFA_COMPONENT_COLLISION_NEWPROXIMITYINTERSECTION_CPP) extern template class SOFA_COMPONENT_COLLISION_DETECTION_INTERSECTION_API IntersectorFactory; #endif diff --git a/Sofa/Component/Collision/Geometry/src/sofa/component/collision/geometry/TriangleModel.h b/Sofa/Component/Collision/Geometry/src/sofa/component/collision/geometry/TriangleModel.h index 3070ce52a66d..fa696451de25 100644 --- a/Sofa/Component/Collision/Geometry/src/sofa/component/collision/geometry/TriangleModel.h +++ b/Sofa/Component/Collision/Geometry/src/sofa/component/collision/geometry/TriangleModel.h @@ -236,7 +236,7 @@ inline TTriangle::TTriangle(ParentModel* model, Index index, helper:: SOFA_UNUSED(x); } -#if !defined(SOFA_COMPONENT_COLLISION_TRIANGLECOLLISIONMODEL_CPP) +#if !defined(SOFA_COMPONENT_COLLISION_TRIANGLECOLLISIONMODEL_CPP) extern template class SOFA_COMPONENT_COLLISION_GEOMETRY_API TTriangle; extern template class SOFA_COMPONENT_COLLISION_GEOMETRY_API TriangleCollisionModel; #endif diff --git a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/PenalityContactForceField.h b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/PenalityContactForceField.h index 131399704be7..382e0c94518c 100644 --- a/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/PenalityContactForceField.h +++ b/Sofa/Component/Collision/Response/Contact/src/sofa/component/collision/response/contact/PenalityContactForceField.h @@ -129,7 +129,7 @@ class PenalityContactForceField : public core::behavior::PairInteractionForceFie }; -#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_PENALITYCONTACTFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_PENALITYCONTACTFORCEFIELD_CPP) extern template class SOFA_COMPONENT_COLLISION_RESPONSE_CONTACT_API PenalityContactForceField; #endif diff --git a/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/IdentityContactMapper.h b/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/IdentityContactMapper.h index aa7f561db9f8..460e5ea36e78 100644 --- a/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/IdentityContactMapper.h +++ b/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/IdentityContactMapper.h @@ -182,7 +182,7 @@ class ContactMapper, sofa::defaulttype::Vec3Types>; extern template class SOFA_COMPONENT_COLLISION_RESPONSE_MAPPER_API ContactMapper, sofa::defaulttype::Vec3Types>; #endif diff --git a/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/RigidContactMapper.h b/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/RigidContactMapper.h index 32d423dc717d..163b3c87c8e8 100644 --- a/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/RigidContactMapper.h +++ b/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/RigidContactMapper.h @@ -147,7 +147,7 @@ class ContactMapper, defaulttype::Vec3Types>; extern template class SOFA_COMPONENT_COLLISION_RESPONSE_MAPPER_API ContactMapper; diff --git a/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/TetrahedronBarycentricContactMapper.h b/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/TetrahedronBarycentricContactMapper.h index c440c95ade0f..c3f0e5987cd4 100644 --- a/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/TetrahedronBarycentricContactMapper.h +++ b/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/TetrahedronBarycentricContactMapper.h @@ -45,7 +45,7 @@ class ContactMapper : } }; -#if !defined(SOFA_COMPONENT_COLLISION_TETRAHEDRONBARYCENTRICCONTACTMAPPER_CPP) +#if !defined(SOFA_COMPONENT_COLLISION_TETRAHEDRONBARYCENTRICCONTACTMAPPER_CPP) extern template class SOFA_COMPONENT_COLLISION_RESPONSE_MAPPER_API ContactMapper; # ifdef _MSC_VER diff --git a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/LinearSolverConstraintCorrection.h b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/LinearSolverConstraintCorrection.h index 2afcb241e700..5545d1445306 100644 --- a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/LinearSolverConstraintCorrection.h +++ b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/LinearSolverConstraintCorrection.h @@ -147,7 +147,7 @@ class LinearSolverConstraintCorrection : public sofa::core::behavior::Constraint bool _new_force; // if true, a "new" force was added in setConstraintDForce which is not yet integrated by a new computation in addConstraintDisplacements }; -#if !defined(SOFA_COMPONENT_CONSTRAINT_LINEARSOLVERCONSTRAINTCORRECTION_CPP) +#if !defined(SOFA_COMPONENT_CONSTRAINT_LINEARSOLVERCONSTRAINTCORRECTION_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_CORRECTION_API LinearSolverConstraintCorrection; extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_CORRECTION_API LinearSolverConstraintCorrection; extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_CORRECTION_API LinearSolverConstraintCorrection; diff --git a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/PrecomputedConstraintCorrection.h b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/PrecomputedConstraintCorrection.h index 7b68edc9d38e..837869ae932f 100644 --- a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/PrecomputedConstraintCorrection.h +++ b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/PrecomputedConstraintCorrection.h @@ -215,7 +215,7 @@ void PrecomputedConstraintCorrection::draw(const core::v -#if !defined(SOFA_COMPONENT_CONSTRAINTSET_PRECOMPUTEDCONSTRAINTCORRECTION_CPP) +#if !defined(SOFA_COMPONENT_CONSTRAINTSET_PRECOMPUTEDCONSTRAINTCORRECTION_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_CORRECTION_API PrecomputedConstraintCorrection; extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_CORRECTION_API PrecomputedConstraintCorrection; extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_CORRECTION_API PrecomputedConstraintCorrection; diff --git a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.h b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.h index 2f8be6779d37..2c7c33f01cbc 100644 --- a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.h +++ b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.h @@ -146,7 +146,7 @@ template<> void UncoupledConstraintCorrection< sofa::defaulttype::Rigid3Types >::getComplianceMatrix(sofa::linearalgebra::BaseMatrix * /*m*/) const; -#if !defined(SOFA_COMPONENT_CONSTRAINTSET_UNCOUPLEDCONSTRAINTCORRECTION_CPP) +#if !defined(SOFA_COMPONENT_CONSTRAINTSET_UNCOUPLEDCONSTRAINTCORRECTION_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_CORRECTION_API UncoupledConstraintCorrection; extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_CORRECTION_API UncoupledConstraintCorrection; extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_CORRECTION_API UncoupledConstraintCorrection; diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.h index 089e84dfd921..19e2a124a907 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.h +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/SlidingConstraint.h @@ -105,7 +105,7 @@ class SlidingConstraint : public core::behavior::PairInteractionConstraint; #endif diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.h index 9fa1915e94aa..42cdea0cfcf6 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.h +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/StopperConstraint.h @@ -119,7 +119,7 @@ class StopperConstraint : public core::behavior::Constraint void getConstraintResolution(const core::ConstraintParams *, std::vector& resTab, unsigned int& offset) override; }; -#if !defined(SOFA_COMPONENT_CONSTRAINTSET_STOPPERCONSTRAINT_CPP) +#if !defined(SOFA_COMPONENT_CONSTRAINTSET_STOPPERCONSTRAINT_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API StopperConstraint; #endif diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.h b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.h index 6f723b7baf35..254103f59fee 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.h +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.h @@ -221,7 +221,7 @@ class UnilateralInteractionConstraint : public core::behavior::PairInteractionCo }; -#if !defined(SOFA_COMPONENT_CONSTRAINTSET_UNILATERALINTERACTIONCONSTRAINT_CPP) +#if !defined(SOFA_COMPONENT_CONSTRAINTSET_UNILATERALINTERACTIONCONSTRAINT_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_MODEL_API UnilateralInteractionConstraint; #endif diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.cpp b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.cpp index ff1389c146f1..433bad30dffd 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.cpp +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.cpp @@ -19,7 +19,7 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFABOUNDARYCONDITION_AFFINEMOVEMENT_CONSTRAINT_CPP +#define SOFABOUNDARYCONDITION_AFFINEMOVEMENTCONSTRAINT_CPP #include #include diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.h index 908ac1d430e3..74f2cae555cc 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AffineMovementConstraint.h @@ -157,10 +157,9 @@ public : void transform(const SetIndexArray & indices, VecCoord& x0 , VecCoord& xf); }; -#if !defined(SOFABOUNDARYCONDITION_AFFINEMOVEMENT_CONSTRAINT_CPP) +#if !defined(SOFABOUNDARYCONDITION_AFFINEMOVEMENTCONSTRAINT_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AffineMovementConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AffineMovementConstraint; - -#endif //SOFABOUNDARYCONDITION_AFFINEMOVEMENT_CONSTRAINT_CPP +#endif //SOFABOUNDARYCONDITION_AFFINEMOVEMENTCONSTRAINT_CPP } // namespace sofa::component::constraint::projective diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.h index 00aaa703e26d..14eff971abb8 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/AttachConstraint.h @@ -113,7 +113,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ATTACHCONSTRAINT_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ATTACHCONSTRAINT_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API AttachConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.h index 203161c096da..7c83fb40cb89 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedConstraint.h @@ -125,7 +125,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDCONSTRAINT_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDCONSTRAINT_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.h index b523781a7d99..cd66b14734a6 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedRotationConstraint.h @@ -72,7 +72,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDROTATIONCONSTRAINT_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDROTATIONCONSTRAINT_CPP) extern template class FixedRotationConstraint; #endif diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.h index d8e39f958be0..29360c586290 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/FixedTranslationConstraint.h @@ -96,7 +96,7 @@ class FixedTranslationConstraint : public core::behavior::ProjectiveConstraintSe }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDTRANSLATIONCONSTRAINT_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_FIXEDTRANSLATIONCONSTRAINT_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API FixedTranslationConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.h index 9de0e3767b40..4df6f686718b 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearMovementConstraint.h @@ -157,7 +157,7 @@ public : }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LINEARMOVEMENTCONSTRAINT_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LINEARMOVEMENTCONSTRAINT_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearMovementConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.h index 8765b925e749..e347423b33b9 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/LinearVelocityConstraint.h @@ -123,7 +123,7 @@ public : void findKeyTimes(); }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LINEARVELOCITYCONSTRAINT_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_LINEARVELOCITYCONSTRAINT_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API LinearVelocityConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.h index b15cd2f4ecdd..ab2389a61daa 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/OscillatorConstraint.h @@ -104,7 +104,7 @@ class OscillatorConstraint : public core::behavior::ProjectiveConstraintSet; extern template class OscillatorConstraint; #endif diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.h index 28c797a7311c..4b6b1bc7c75b 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ParabolicConstraint.h @@ -118,7 +118,7 @@ class ParabolicConstraint : public core::behavior::ProjectiveConstraintSet; extern template class ParabolicConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.h index 41b018db2a50..b54bdc2b6119 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialFixedConstraint.h @@ -93,7 +93,7 @@ class PartialFixedConstraint : public FixedConstraint const std::function& clear); }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARTIALFIXEDCONSTRAINT_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARTIALFIXEDCONSTRAINT_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialFixedConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.h index ca8e15f467c2..072548a50301 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PartialLinearMovementConstraint.h @@ -165,7 +165,7 @@ public : }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARTIALLINEARMOVEMENTCONSTRAINT_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PARTIALLINEARMOVEMENTCONSTRAINT_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PartialLinearMovementConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.h index a3908cf0d303..2a53250282d4 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PatchTestMovementConstraint.h @@ -156,7 +156,7 @@ public : }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PATCHTESTMOVEMENTCONSTRAINT_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_PATCHTESTMOVEMENTCONSTRAINT_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PatchTestMovementConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PatchTestMovementConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.h index 1a0117c4dfcd..d861e5a7a727 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/PositionBasedDynamicsConstraint.h @@ -101,7 +101,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_POSITIONBASEDDYNAMICSCONSTRAINT_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_POSITIONBASEDDYNAMICSCONSTRAINT_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API PositionBasedDynamicsConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.h index 375e4d7abe65..73b8f78525cd 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectDirectionConstraint.h @@ -125,7 +125,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectDirectionConstraint_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectDirectionConstraint_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectDirectionConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectDirectionConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.h index 2614ddfbc592..9e30c5687d7d 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToLineConstraint.h @@ -129,7 +129,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectToLineConstraint_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectToLineConstraint_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToLineConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToLineConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.h index b1184d892ca8..925bf007d652 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPlaneConstraint.h @@ -127,7 +127,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectToPlaneConstraint_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectToPlaneConstraint_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPlaneConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPlaneConstraint; diff --git a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.h b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.h index df57029a954b..91a50f2b7c09 100644 --- a/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.h +++ b/Sofa/Component/Constraint/Projective/src/sofa/component/constraint/projective/ProjectToPointConstraint.h @@ -120,7 +120,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectToPointConstraint_CPP) +#if !defined(SOFA_COMPONENT_PROJECTIVECONSTRAINTSET_ProjectToPointConstraint_CPP) extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPointConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPointConstraint; extern template class SOFA_COMPONENT_CONSTRAINT_PROJECTIVE_API ProjectToPointConstraint; diff --git a/Sofa/Component/Controller/src/sofa/component/controller/MechanicalStateController.h b/Sofa/Component/Controller/src/sofa/component/controller/MechanicalStateController.h index a4207c2a969f..34a15256e65a 100644 --- a/Sofa/Component/Controller/src/sofa/component/controller/MechanicalStateController.h +++ b/Sofa/Component/Controller/src/sofa/component/controller/MechanicalStateController.h @@ -149,7 +149,7 @@ class MechanicalStateController : public Controller bool buttonDevice; }; -#if !defined(SOFA_COMPONENT_CONTROLLER_MECHANICALSTATECONTROLLER_CPP) +#if !defined(SOFA_COMPONENT_CONTROLLER_MECHANICALSTATECONTROLLER_CPP) extern template class SOFA_COMPONENT_CONTROLLER_API MechanicalStateController; extern template class SOFA_COMPONENT_CONTROLLER_API MechanicalStateController; #endif diff --git a/Sofa/Component/Diffusion/src/sofa/component/diffusion/TetrahedronDiffusionFEMForceField.h b/Sofa/Component/Diffusion/src/sofa/component/diffusion/TetrahedronDiffusionFEMForceField.h index a39b38afb912..7b2afa1a7108 100644 --- a/Sofa/Component/Diffusion/src/sofa/component/diffusion/TetrahedronDiffusionFEMForceField.h +++ b/Sofa/Component/Diffusion/src/sofa/component/diffusion/TetrahedronDiffusionFEMForceField.h @@ -134,7 +134,7 @@ class TetrahedronDiffusionFEMForceField : public core::behavior::ForceField; extern template class SOFA_COMPONENT_DIFFUSION_API TetrahedronDiffusionFEMForceField; extern template class SOFA_COMPONENT_DIFFUSION_API TetrahedronDiffusionFEMForceField; diff --git a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/AverageCoord.h b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/AverageCoord.h index a10bca618c75..1adfd33caa5a 100644 --- a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/AverageCoord.h +++ b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/AverageCoord.h @@ -67,7 +67,7 @@ class AverageCoord : public core::DataEngine, public core::behavior::SingleState void onBeginAnimationStep(const double /*dt*/); }; -#if !defined(SOFA_COMPONENT_ENGINE_AverageCoord_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_AverageCoord_CPP) extern template class SOFA_COMPONENT_ENGINE_ANALYZE_API AverageCoord; extern template class SOFA_COMPONENT_ENGINE_ANALYZE_API AverageCoord; extern template class SOFA_COMPONENT_ENGINE_ANALYZE_API AverageCoord; diff --git a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/ClusteringEngine.h b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/ClusteringEngine.h index 58899fbe43b0..887691e8672d 100644 --- a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/ClusteringEngine.h +++ b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/ClusteringEngine.h @@ -113,7 +113,7 @@ class ClusteringEngine : public core::DataEngine bool save(); }; -#if !defined(SOFA_COMPONENT_ENGINE_CLUSTERINGENGINE_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_CLUSTERINGENGINE_CPP) extern template class SOFA_COMPONENT_ENGINE_ANALYZE_API ClusteringEngine; #endif diff --git a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/Distances.h b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/Distances.h index 8fdf4a2a10e1..b832087431ca 100644 --- a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/Distances.h +++ b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/Distances.h @@ -218,7 +218,7 @@ class Distances : public core::DataEngine inline void addContribution ( double& valueWrite, int& nbTest, double*** valueRead, const int& x, const int& y, const int& z, const int coeff, const bool& useStiffnessMap ); }; -#if !defined(SOFA_COMPONENT_ENGINE_DISTANCES_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_DISTANCES_CPP) extern template class SOFA_COMPONENT_ENGINE_ANALYZE_API Distances; #endif diff --git a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/HausdorffDistance.h b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/HausdorffDistance.h index 8505fe160703..e183b7d5b8c8 100644 --- a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/HausdorffDistance.h +++ b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/HausdorffDistance.h @@ -79,7 +79,7 @@ class HausdorffDistance : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_HAUSDORFFDISTANCE_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_HAUSDORFFDISTANCE_CPP) extern template class SOFA_COMPONENT_ENGINE_ANALYZE_API HausdorffDistance; extern template class SOFA_COMPONENT_ENGINE_ANALYZE_API HausdorffDistance; extern template class SOFA_COMPONENT_ENGINE_ANALYZE_API HausdorffDistance; diff --git a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/ShapeMatching.h b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/ShapeMatching.h index 5c98cfe1525c..f049c899c3a2 100644 --- a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/ShapeMatching.h +++ b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/ShapeMatching.h @@ -95,7 +95,7 @@ class ShapeMatching : public core::DataEngine, public core::behavior::SingleStat }; -#if !defined(SOFA_COMPONENT_ENGINE_SHAPEMATCHING_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_SHAPEMATCHING_CPP) extern template class SOFA_COMPONENT_ENGINE_ANALYZE_API ShapeMatching; extern template class SOFA_COMPONENT_ENGINE_ANALYZE_API ShapeMatching; diff --git a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/SumEngine.h b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/SumEngine.h index e559291b0f34..ff48e921caca 100644 --- a/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/SumEngine.h +++ b/Sofa/Component/Engine/Analyze/src/sofa/component/engine/analyze/SumEngine.h @@ -53,7 +53,7 @@ class SumEngine : public core::DataEngine Data d_output; ///< output sum }; -#if !defined(SOFA_COMPONENT_ENGINE_SumEngine_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_SumEngine_CPP) extern template class SOFA_COMPONENT_ENGINE_ANALYZE_API SumEngine; extern template class SOFA_COMPONENT_ENGINE_ANALYZE_API SumEngine; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/ExtrudeEdgesAndGenerateQuads.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/ExtrudeEdgesAndGenerateQuads.h index 29648e4ba93c..3ccd29db3726 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/ExtrudeEdgesAndGenerateQuads.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/ExtrudeEdgesAndGenerateQuads.h @@ -76,7 +76,7 @@ class ExtrudeEdgesAndGenerateQuads : public core::DataEngine void checkInput(); }; -#if !defined(SOFA_COMPONENT_ENGINE_EXTRUDEEDGESANDGENERATEQUADS_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_EXTRUDEEDGESANDGENERATEQUADS_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API ExtrudeEdgesAndGenerateQuads; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/ExtrudeQuadsAndGenerateHexas.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/ExtrudeQuadsAndGenerateHexas.h index 6fa2ae248368..dc7742a8eb94 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/ExtrudeQuadsAndGenerateHexas.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/ExtrudeQuadsAndGenerateHexas.h @@ -78,7 +78,7 @@ class ExtrudeQuadsAndGenerateHexas : public core::DataEngine Data< type::vector > f_extrudedHexas; ///< List of hexahedra generated during the extrusion }; -#if !defined(SOFA_COMPONENT_ENGINE_EXTRUDEQUADSANDGENERATEHEXAS_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_EXTRUDEQUADSANDGENERATEHEXAS_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API ExtrudeQuadsAndGenerateHexas; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/ExtrudeSurface.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/ExtrudeSurface.h index 2e6724833d26..787442e989ce 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/ExtrudeSurface.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/ExtrudeSurface.h @@ -73,7 +73,7 @@ class ExtrudeSurface : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_EXTRUDESURFACE_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_EXTRUDESURFACE_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API ExtrudeSurface; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateCylinder.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateCylinder.h index c1963ac38017..02582c9d4130 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateCylinder.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateCylinder.h @@ -84,7 +84,7 @@ class GenerateCylinder : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_GENERATECYLINDER_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_GENERATECYLINDER_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API GenerateCylinder; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateGrid.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateGrid.h index 5b5799809410..7c2e2cce47c8 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateGrid.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateGrid.h @@ -81,7 +81,7 @@ class GenerateGrid : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_GENERATEGRID_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_GENERATEGRID_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API GenerateGrid; extern template class SOFA_COMPONENT_ENGINE_GENERATE_API GenerateGrid; diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateRigidMass.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateRigidMass.h index 50c0a33c3290..d0c8f7427f73 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateRigidMass.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateRigidMass.h @@ -95,7 +95,7 @@ class GenerateRigidMass : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_GENERATERIGIDMASS_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_GENERATERIGIDMASS_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API GenerateRigidMass; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateSphere.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateSphere.h index d2b7cac8c1a8..aab693c3fb54 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateSphere.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GenerateSphere.h @@ -93,7 +93,7 @@ class GenerateSphere : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_GENERATESPHERE_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_GENERATESPHERE_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API GenerateSphere; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GroupFilterYoungModulus.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GroupFilterYoungModulus.h index fac712ea5049..0ba654b89d92 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GroupFilterYoungModulus.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/GroupFilterYoungModulus.h @@ -65,7 +65,7 @@ class GroupFilterYoungModulus : public core::DataEngine Data > p_groupMod; ///< list of young modulus for each group }; -#if !defined(SOFA_COMPONENT_ENGINE_GROUPFILTERYOUNGMODULUS_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_GROUPFILTERYOUNGMODULUS_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API GroupFilterYoungModulus; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/JoinPoints.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/JoinPoints.h index f89773cda54f..333b594aa221 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/JoinPoints.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/JoinPoints.h @@ -71,7 +71,7 @@ class JoinPoints : public sofa::core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_JOINPOINTS_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_JOINPOINTS_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API JoinPoints; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergeMeshes.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergeMeshes.h index 6131e27be5a4..6ff8d2abe421 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergeMeshes.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergeMeshes.h @@ -152,7 +152,7 @@ class MergeMeshes : public core::DataEngine } }; -#if !defined(SOFA_COMPONENT_ENGINE_MERGEMESHES_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_MERGEMESHES_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MergeMeshes; extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MergeMeshes; extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MergeMeshes; diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergePoints.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergePoints.h index d50df8033539..ed690e72b86b 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergePoints.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergePoints.h @@ -66,7 +66,7 @@ class MergePoints : public core::DataEngine Data f_noUpdate; ///< do not update the output at eacth time step (false) }; -#if !defined(SOFA_COMPONENT_ENGINE_MERGEPOINTS_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_MERGEPOINTS_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MergePoints; extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MergePoints; extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MergePoints; diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergeSets.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergeSets.h index 98bdfbea56ea..c10e5a24d220 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergeSets.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergeSets.h @@ -59,7 +59,7 @@ class MergeSets : public core::DataEngine Data f_op; ///< name of operation to compute (union, intersection, difference, symmetric_difference) }; -#if !defined(SOFA_COMPONENT_ENGINE_MERGESETS_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_MERGESETS_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MergeSets; extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MergeSets; //extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MergeSets; diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergeVectors.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergeVectors.h index d668e70c4292..b9a2272d6733 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergeVectors.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MergeVectors.h @@ -64,7 +64,7 @@ class MergeVectors : public core::DataEngine Data f_output; ///< Output vector }; -#if !defined(SOFA_COMPONENT_ENGINE_MERGEVECTORS_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_MERGEVECTORS_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MergeVectors< type::vector >; extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MergeVectors< type::vector >; extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MergeVectors< type::vector >; diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MeshBarycentricMapperEngine.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MeshBarycentricMapperEngine.h index be09a3c7276d..508294e1f716 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MeshBarycentricMapperEngine.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MeshBarycentricMapperEngine.h @@ -88,7 +88,7 @@ class MeshBarycentricMapperEngine : public core::DataEngine -#if !defined(SOFA_COMPONENT_ENGINE_MESHBARYCENTRICMAPPERENGINE_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_MESHBARYCENTRICMAPPERENGINE_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MeshBarycentricMapperEngine; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MeshClosingEngine.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MeshClosingEngine.h index 02898f8d78bb..c0534374b2bc 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MeshClosingEngine.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/MeshClosingEngine.h @@ -106,7 +106,7 @@ class MeshClosingEngine : public core::DataEngine void doUpdate() override; }; -#if !defined(SOFA_COMPONENT_ENGINE_MeshClosingEngine_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_MeshClosingEngine_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API MeshClosingEngine; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/NormEngine.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/NormEngine.h index 1036235e268a..edb1923d4b7a 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/NormEngine.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/NormEngine.h @@ -59,7 +59,7 @@ class NormEngine : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_NORMENGINE_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_NORMENGINE_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API NormEngine; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/NormalsFromPoints.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/NormalsFromPoints.h index 5c722d44ac37..e8218266fac2 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/NormalsFromPoints.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/NormalsFromPoints.h @@ -64,7 +64,7 @@ class NormalsFromPoints : public core::DataEngine Data useAngles; ///< Use incident angles to weight faces normal contributions at each vertex }; -#if !defined(SOFA_COMPONENT_ENGINE_NormalsFromPoints_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_NormalsFromPoints_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API NormalsFromPoints; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/RandomPointDistributionInSurface.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/RandomPointDistributionInSurface.h index 85a78958a6ac..5bf1b0c5d36d 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/RandomPointDistributionInSurface.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/RandomPointDistributionInSurface.h @@ -90,7 +90,7 @@ class RandomPointDistributionInSurface : public core::DataEngine bool testDistance(Coord p); }; -#if !defined(SOFA_COMPONENT_ENGINE_RANDOMPOINTDISTRIBUTIONINSURFACE_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_RANDOMPOINTDISTRIBUTIONINSURFACE_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API RandomPointDistributionInSurface; #endif diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/Spiral.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/Spiral.h index f66cdfc75e39..ed3938f45298 100644 --- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/Spiral.h +++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/Spiral.h @@ -65,7 +65,7 @@ class Spiral : public core::DataEngine Data curvature; ///< Spiral curvature factor }; -#if !defined(SOFA_COMPONENT_ENGINE_SPIRAL_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_SPIRAL_CPP) extern template class SOFA_COMPONENT_ENGINE_GENERATE_API Spiral; #endif diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/BoxROI.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/BoxROI.h index e2eb1f64fb55..14417281c453 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/BoxROI.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/BoxROI.h @@ -188,7 +188,7 @@ class BoxROI : public DataEngine void getPointsFromOrientedBox(const Vec10& box, vector &points); }; -#if !defined(SOFA_COMPONENT_ENGINE_BOXROI_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_BOXROI_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API BoxROI; extern template class SOFA_COMPONENT_ENGINE_SELECT_API BoxROI; extern template class SOFA_COMPONENT_ENGINE_SELECT_API BoxROI; diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ComplementaryROI.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ComplementaryROI.h index b8da48cc6506..a5abd2c42149 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ComplementaryROI.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ComplementaryROI.h @@ -82,7 +82,7 @@ class ComplementaryROI : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_COMPLEMENTARYROI_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_COMPLEMENTARYROI_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API ComplementaryROI; diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/IndicesFromValues.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/IndicesFromValues.h index 87579b2d3e74..28ea9777b486 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/IndicesFromValues.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/IndicesFromValues.h @@ -66,7 +66,7 @@ class IndicesFromValues : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_INDICESFROMVALUES_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_INDICESFROMVALUES_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API IndicesFromValues; extern template class SOFA_COMPONENT_ENGINE_SELECT_API IndicesFromValues; extern template class SOFA_COMPONENT_ENGINE_SELECT_API IndicesFromValues; diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshROI.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshROI.h index 294c1703c815..1bd346094c56 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshROI.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshROI.h @@ -149,11 +149,10 @@ class MeshROI : public core::DataEngine Data d_doUpdate; ///< Update the computation (not only at the init) }; -#if !defined(SOFA_COMPONENT_ENGINE_MESHROI_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_MESHROI_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API MeshROI; extern template class SOFA_COMPONENT_ENGINE_SELECT_API MeshROI; -extern template class SOFA_COMPONENT_ENGINE_SELECT_API MeshROI; //Phuoc - +extern template class SOFA_COMPONENT_ENGINE_SELECT_API MeshROI; #endif } //namespace sofa::component::engine::select diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshSampler.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshSampler.h index 35917d784710..a72b85377866 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshSampler.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshSampler.h @@ -92,7 +92,7 @@ class MeshSampler : public core::DataEngine void computeNeighbors(VVI& ngb); }; -#if !defined(SOFA_COMPONENT_ENGINE_MESHSAMPLER_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_MESHSAMPLER_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API MeshSampler; #endif diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshSplittingEngine.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshSplittingEngine.h index 3f70cdaaff82..fec8403c7460 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshSplittingEngine.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshSplittingEngine.h @@ -143,7 +143,7 @@ class MeshSplittingEngine : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_MeshSplittingEngine_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_MeshSplittingEngine_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API MeshSplittingEngine; #endif diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshSubsetEngine.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshSubsetEngine.h index 286259e20738..ffc25b1c806b 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshSubsetEngine.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/MeshSubsetEngine.h @@ -81,7 +81,7 @@ class MeshSubsetEngine : public core::DataEngine void doUpdate() override; }; -#if !defined(SOFA_COMPONENT_ENGINE_MeshSubsetEngine_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_MeshSubsetEngine_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API MeshSubsetEngine; #endif diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/NearestPointROI.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/NearestPointROI.h index 8a910ffc48d0..c3bfc53f8fbb 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/NearestPointROI.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/NearestPointROI.h @@ -88,7 +88,7 @@ class NearestPointROI : public sofa::core::DataEngine, public core::behavior::Pa }; -#if !defined(SOFA_COMPONENT_ENGINE_NearestPointROI_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_NearestPointROI_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API NearestPointROI; extern template class SOFA_COMPONENT_ENGINE_SELECT_API NearestPointROI; extern template class SOFA_COMPONENT_ENGINE_SELECT_API NearestPointROI; diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/PairBoxRoi.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/PairBoxRoi.h index f2fa453a3fee..496a4b70b948 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/PairBoxRoi.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/PairBoxRoi.h @@ -114,7 +114,7 @@ class PairBoxROI : public core::DataEngine Data _drawSize; ///< Draw Size }; -#if !defined(SOFA_COMPONENT_ENGINE_PAIRBOXROI_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_PAIRBOXROI_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API PairBoxROI; extern template class SOFA_COMPONENT_ENGINE_SELECT_API PairBoxROI; extern template class SOFA_COMPONENT_ENGINE_SELECT_API PairBoxROI; //Phuoc diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/PlaneROI.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/PlaneROI.h index 623bfeb2043d..e379506ebf2f 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/PlaneROI.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/PlaneROI.h @@ -135,7 +135,7 @@ class PlaneROI : public core::DataEngine Real width, length, depth; }; -#if !defined(SOFA_COMPONENT_ENGINE_PLANEROI_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_PLANEROI_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API PlaneROI; extern template class SOFA_COMPONENT_ENGINE_SELECT_API PlaneROI; diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/PointsFromIndices.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/PointsFromIndices.h index 8f4a7bfe4649..7e39f513899c 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/PointsFromIndices.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/PointsFromIndices.h @@ -65,7 +65,7 @@ class PointsFromIndices : public core::DataEngine bool contains(VecCoord& v, Coord c); }; -#if !defined(SOFA_COMPONENT_ENGINE_POINTSFROMINDICES_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_POINTSFROMINDICES_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API PointsFromIndices; #endif diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ProximityROI.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ProximityROI.h index 138de78778cd..cbfba0f9b471 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ProximityROI.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ProximityROI.h @@ -106,7 +106,7 @@ class ProximityROI : public core::DataEngine Data _drawSize; ///< rendering size for box and topological elements }; -#if !defined(SOFA_COMPONENT_ENGINE_PROXIMITYROI_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_PROXIMITYROI_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API ProximityROI; #endif diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/SphereROI.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/SphereROI.h index 2ec8977cee7c..ca9a76091e0b 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/SphereROI.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/SphereROI.h @@ -157,7 +157,7 @@ template<> bool SphereROI::isTetrahedronInSphere(const template<> void SphereROI::doUpdate(); -#if !defined(SOFA_COMPONENT_ENGINE_SPHEREROI_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_SPHEREROI_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API SphereROI; extern template class SOFA_COMPONENT_ENGINE_SELECT_API SphereROI; #endif diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/SubsetTopology.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/SubsetTopology.h index b1dadc3f61ee..e6cfb51c47d1 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/SubsetTopology.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/SubsetTopology.h @@ -171,7 +171,7 @@ class SubsetTopology : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_SUBSETTOPOLOGY_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_SUBSETTOPOLOGY_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API SubsetTopology; extern template class SOFA_COMPONENT_ENGINE_SELECT_API SubsetTopology; #endif diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ValuesFromIndices.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ValuesFromIndices.h index f6f265c0d03c..4c17af008a03 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ValuesFromIndices.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ValuesFromIndices.h @@ -65,7 +65,7 @@ class ValuesFromIndices : public core::DataEngine Data f_outStr; ///< Output values corresponding to the indices, converted as a string }; -#if !defined(SOFA_COMPONENT_ENGINE_VALUESFROMINDICES_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_VALUESFROMINDICES_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API ValuesFromIndices; extern template class SOFA_COMPONENT_ENGINE_SELECT_API ValuesFromIndices; extern template class SOFA_COMPONENT_ENGINE_SELECT_API ValuesFromIndices; diff --git a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ValuesFromPositions.h b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ValuesFromPositions.h index 95e28bd09d81..0c96979d6a24 100644 --- a/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ValuesFromPositions.h +++ b/Sofa/Component/Engine/Select/src/sofa/component/engine/select/ValuesFromPositions.h @@ -139,7 +139,7 @@ class ValuesFromPositions : public core::DataEngine Data p_vectorLength; ///< vector length visualisation. }; -#if !defined(SOFA_COMPONENT_ENGINE_VALUESFROMPOSITIONS_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_VALUESFROMPOSITIONS_CPP) extern template class SOFA_COMPONENT_ENGINE_SELECT_API ValuesFromPositions; extern template class SOFA_COMPONENT_ENGINE_SELECT_API ValuesFromPositions; #endif diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/DifferenceEngine.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/DifferenceEngine.h index f60c6699eec0..3e6f3cd65eaa 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/DifferenceEngine.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/DifferenceEngine.h @@ -59,7 +59,7 @@ class DifferenceEngine : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_DifferenceEngine_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_DifferenceEngine_CPP) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API DifferenceEngine; extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API DifferenceEngine; diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/DilateEngine.cpp b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/DilateEngine.cpp index 70cc7efb516b..436b8d0bf096 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/DilateEngine.cpp +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/DilateEngine.cpp @@ -19,6 +19,7 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ +#define SOFA_COMPONENT_ENGINE_DILATEENGINE_CPP #include #include diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/DilateEngine.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/DilateEngine.h index 9a7efc37663d..7b21a0a14296 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/DilateEngine.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/DilateEngine.h @@ -72,7 +72,7 @@ class DilateEngine : public core::DataEngine Data d_minThickness; ///< minimal thickness to enforce }; -#if !defined(SOFA_COMPONENT_ENGINE_DILATEENGINE_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_DILATEENGINE_CPP) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API DilateEngine; #endif diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/IndexValueMapper.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/IndexValueMapper.h index 103bfc751f38..c007643b1bf4 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/IndexValueMapper.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/IndexValueMapper.h @@ -63,7 +63,7 @@ class IndexValueMapper : public sofa::core::DataEngine }; -#if !defined(INDEXVALUEMAPPER_CPP_) +#if !defined(INDEXVALUEMAPPER_CPP_) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API IndexValueMapper; #endif diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/Indices2ValuesMapper.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/Indices2ValuesMapper.h index 4727ab5a7c45..040e0dfad147 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/Indices2ValuesMapper.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/Indices2ValuesMapper.h @@ -65,7 +65,7 @@ class Indices2ValuesMapper : public sofa::core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_INDICES2VALUESMAPPER_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_INDICES2VALUESMAPPER_CPP) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API Indices2ValuesMapper; #endif diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/MapIndices.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/MapIndices.h index 31681beb30c6..cfa73d0aef67 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/MapIndices.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/MapIndices.h @@ -73,7 +73,7 @@ class MapIndices : public core::DataEngine void apply(Value& v, const MapIndex& m); }; -#if !defined(SOFA_COMPONENT_ENGINE_MAPINDICES_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_MAPINDICES_CPP) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API MapIndices; extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API MapIndices; extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API MapIndices< type::fixed_array >; diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/MathOp.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/MathOp.h index 21be0bb46796..4628604d4c4c 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/MathOp.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/MathOp.h @@ -69,7 +69,7 @@ class MathOp : public core::DataEngine void createInputs(int nb = -1); }; -#if !defined(SOFA_COMPONENT_ENGINE_MATHOP_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_MATHOP_CPP) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API MathOp< type::vector >; extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API MathOp< type::vector >; diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/ProjectiveTransformEngine.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/ProjectiveTransformEngine.h index 6c6783e6d99e..57f1b8874284 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/ProjectiveTransformEngine.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/ProjectiveTransformEngine.h @@ -69,7 +69,7 @@ class ProjectiveTransformEngine : public core::DataEngine Data focal_distance; ///< focal distance i.e. distance between the optical center and the image plane }; -#if !defined(SOFA_COMPONENT_ENGINE_PROJECTIVETRANSFORMENGINE_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_PROJECTIVETRANSFORMENGINE_CPP) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API ProjectiveTransformEngine; diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/QuatToRigidEngine.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/QuatToRigidEngine.h index 18d2c6a69752..05a128412091 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/QuatToRigidEngine.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/QuatToRigidEngine.h @@ -62,7 +62,7 @@ class QuatToRigidEngine : public sofa::core::DataEngine Data > f_rigids; ///< Rigid (Position + Orientation) }; -#if !defined(QUATTORIGIDENGINE_CPP) +#if !defined(QUATTORIGIDENGINE_CPP) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API QuatToRigidEngine; #endif diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/RigidToQuatEngine.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/RigidToQuatEngine.h index b22d2373b456..3e77775c0069 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/RigidToQuatEngine.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/RigidToQuatEngine.h @@ -61,7 +61,7 @@ class RigidToQuatEngine : public sofa::core::DataEngine Data > f_rigids; ///< Rigid (Position + Orientation) }; -#if !defined(RIGIDTOQUATENGINE_CPP) +#if !defined(RIGIDTOQUATENGINE_CPP) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API RigidToQuatEngine; #endif diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/SmoothMeshEngine.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/SmoothMeshEngine.h index e3ae78aa3919..f6d4e245e696 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/SmoothMeshEngine.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/SmoothMeshEngine.h @@ -72,7 +72,7 @@ class SmoothMeshEngine : public core::DataEngine sofa::core::topology::BaseMeshTopology* m_topology; }; -#if !defined(SOFA_COMPONENT_ENGINE_SMOOTHMESHENGINE_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_SMOOTHMESHENGINE_CPP) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API SmoothMeshEngine; #endif diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/TransformEngine.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/TransformEngine.h index 3e7b2af456d9..c8d8c264c51f 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/TransformEngine.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/TransformEngine.h @@ -68,7 +68,7 @@ class TransformEngine : public core::DataEngine Data inverse; ///< true to apply inverse transformation }; -#if !defined(SOFA_COMPONENT_ENGINE_TRANSFORMENGINE_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_TRANSFORMENGINE_CPP) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API TransformEngine; extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API TransformEngine; extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API TransformEngine; diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/TransformPosition.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/TransformPosition.h index 8835f51126ab..ee6e6fe75c5c 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/TransformPosition.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/TransformPosition.h @@ -111,7 +111,7 @@ class TransformPosition : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_TRANSFORMPOSITION_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_TRANSFORMPOSITION_CPP) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API TransformPosition; #endif diff --git a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/Vertex2Frame.h b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/Vertex2Frame.h index 11adc173d637..5929bc091306 100644 --- a/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/Vertex2Frame.h +++ b/Sofa/Component/Engine/Transform/src/sofa/component/engine/transform/Vertex2Frame.h @@ -76,7 +76,7 @@ class Vertex2Frame : public core::DataEngine }; -#if !defined(SOFA_COMPONENT_ENGINE_VERTEX2FRAME_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_VERTEX2FRAME_CPP) extern template class SOFA_COMPONENT_ENGINE_TRANSFORM_API Vertex2Frame; #endif diff --git a/Sofa/Component/Haptics/src/sofa/component/haptics/LCPForceFeedback.h b/Sofa/Component/Haptics/src/sofa/component/haptics/LCPForceFeedback.h index 998ce6470713..bb9848019319 100644 --- a/Sofa/Component/Haptics/src/sofa/component/haptics/LCPForceFeedback.h +++ b/Sofa/Component/Haptics/src/sofa/component/haptics/LCPForceFeedback.h @@ -136,7 +136,7 @@ class LCPForceFeedback : public MechanicalStateForceFeedback std::mutex lockForce; }; -#if !defined(SOFA_COMPONENT_CONTROLLER_LCPFORCEFEEDBACK_CPP) +#if !defined(SOFA_COMPONENT_CONTROLLER_LCPFORCEFEEDBACK_CPP) extern template class SOFA_COMPONENT_HAPTICS_API LCPForceFeedback; extern template class SOFA_COMPONENT_HAPTICS_API LCPForceFeedback; #endif diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/AsyncSparseLDLSolver.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/AsyncSparseLDLSolver.h index 26dbd7c7eb6b..d64eef844886 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/AsyncSparseLDLSolver.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/AsyncSparseLDLSolver.h @@ -102,7 +102,7 @@ class AsyncSparseLDLSolver : public SparseLDLSolver, sofa::linearalgebra::FullVector >; extern template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API AsyncSparseLDLSolver< sofa::linearalgebra::CompressedRowSparseMatrix< type::Mat<3, 3, SReal> >, sofa::linearalgebra::FullVector >; #endif diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/BTDLinearSolver.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/BTDLinearSolver.h index 7302ca5b39d5..36aba9eadfef 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/BTDLinearSolver.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/BTDLinearSolver.h @@ -174,7 +174,7 @@ class BTDLinearSolver : public sofa::component::linearsolver::MatrixLinearSolver }; -#if !defined(SOFA_COMPONENT_LINEARSOLVER_BTDLINEARSOLVER_CPP) +#if !defined(SOFA_COMPONENT_LINEARSOLVER_BTDLINEARSOLVER_CPP) extern template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API BTDLinearSolver< linearalgebra::BTDMatrix<6, SReal>, linearalgebra::BlockVector<6, SReal> >; #endif } //namespace sofa::component::linearsolver::direct diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/CholeskySolver.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/CholeskySolver.h index b93972405700..5f4269c62b92 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/CholeskySolver.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/CholeskySolver.h @@ -63,7 +63,7 @@ private : linearalgebra::FullMatrix L; }; -#if !defined(SOFA_COMPONENT_LINEARSOLVER_CHOLESKYSOLVER_CPP) +#if !defined(SOFA_COMPONENT_LINEARSOLVER_CHOLESKYSOLVER_CPP) extern template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API CholeskySolver< linearalgebra::SparseMatrix, linearalgebra::FullVector >; extern template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API CholeskySolver< linearalgebra::FullMatrix, linearalgebra::FullVector >; diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.h index 83dce1353f31..9fd72c37db46 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.h @@ -73,7 +73,7 @@ class SparseCholeskySolver : public sofa::component::linearsolver::MatrixLinearS css* symbolic_Chol(cs *A); }; -#if !defined(SOFA_COMPONENT_LINEARSOLVER_SPARSECHOLESKYSOLVER_CPP) +#if !defined(SOFA_COMPONENT_LINEARSOLVER_SPARSECHOLESKYSOLVER_CPP) extern template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API SparseCholeskySolver< sofa::linearalgebra::CompressedRowSparseMatrix, sofa::linearalgebra::FullVector >; #endif diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.h index 9b3fc7dc8580..e0c47e855837 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.h @@ -82,7 +82,7 @@ protected : void showInvalidSystemMessage(const std::string& reason) const; }; -#if !defined(SOFA_COMPONENT_LINEARSOLVER_SPARSELDLSOLVER_CPP) +#if !defined(SOFA_COMPONENT_LINEARSOLVER_SPARSELDLSOLVER_CPP) extern template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API SparseLDLSolver< sofa::linearalgebra::CompressedRowSparseMatrix< SReal>, sofa::linearalgebra::FullVector >; extern template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API SparseLDLSolver< sofa::linearalgebra::CompressedRowSparseMatrix< type::Mat<3,3,SReal> >, sofa::linearalgebra::FullVector >; #endif diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.h index b8aa326ec46b..b6ebba1a2adc 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.h @@ -101,7 +101,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_LINEARSOLVER_SPARSELUSOLVER_CPP) +#if !defined(SOFA_COMPONENT_LINEARSOLVER_SPARSELUSOLVER_CPP) extern template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API SparseLUSolver< sofa::linearalgebra::CompressedRowSparseMatrix< SReal>, sofa::linearalgebra::FullVector >; #endif diff --git a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/CGLinearSolver.h b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/CGLinearSolver.h index 5b4858ed0091..e45c103b9a39 100644 --- a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/CGLinearSolver.h +++ b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/CGLinearSolver.h @@ -78,7 +78,7 @@ inline void CGLinearSolver inline void CGLinearSolver::cgstep_alpha(const core::ExecParams* params, Vector& x, Vector& r, Vector& p, Vector& q, Real alpha); -#if !defined(SOFA_COMPONENT_LINEARSOLVER_CGLINEARSOLVER_CPP) +#if !defined(SOFA_COMPONENT_LINEARSOLVER_CGLINEARSOLVER_CPP) extern template class SOFA_COMPONENT_LINEARSOLVER_ITERATIVE_API CGLinearSolver< GraphScatteredMatrix, GraphScatteredVector >; extern template class SOFA_COMPONENT_LINEARSOLVER_ITERATIVE_API CGLinearSolver< linearalgebra::FullMatrix, linearalgebra::FullVector >; extern template class SOFA_COMPONENT_LINEARSOLVER_ITERATIVE_API CGLinearSolver< linearalgebra::SparseMatrix, linearalgebra::FullVector >; diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.h index 435eaf202be7..5fb8323ae76c 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.h @@ -119,7 +119,7 @@ class BarycentricMapperTetrahedronSetTopology< sofa::defaulttype::StdVectorTypes -#if !defined(SOFA_COMPONENT_MAPPING_BARYCENTRICMAPPINGRIGID_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_BARYCENTRICMAPPINGRIGID_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API BarycentricMapping< defaulttype::Vec3Types, defaulttype::Rigid3Types >; extern template class SOFA_COMPONENT_MAPPING_LINEAR_API BarycentricMapperRegularGridTopology< defaulttype::Vec3Types, defaulttype::Rigid3Types >; extern template class SOFA_COMPONENT_MAPPING_LINEAR_API BarycentricMapperSparseGridTopology< defaulttype::Vec3Types, defaulttype::Rigid3Types >; diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BeamLinearMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BeamLinearMapping.h index e76b254c3e70..cd5ae4ee1560 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BeamLinearMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BeamLinearMapping.h @@ -112,8 +112,8 @@ class BeamLinearMapping : public core::Mapping template struct RigidMappingMatrixHelper; -#if !defined(SOFA_COMPONENT_MAPPING_BEAMLINEARMAPPING_CPP) -extern template class SOFA_COMPONENT_MAPPING_LINEAR_API BeamLinearMapping< defaulttype::Rigid3Types, defaulttype::Vec3dTypes >; +#if !defined(SOFA_COMPONENT_MAPPING_BEAMLINEARMAPPING_CPP) +extern template class SOFA_COMPONENT_MAPPING_LINEAR_API BeamLinearMapping< defaulttype::Rigid3Types, defaulttype::Vec3Types >; #endif } // namespace sofa::component::mapping::linear diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMapping.cpp b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMapping.cpp index a9ff6bf0e1b0..dd35f79ef856 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMapping.cpp +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMapping.cpp @@ -38,6 +38,7 @@ int CenterOfMassMappingClass = core::RegisterObject("Set the point to the center ; template class SOFA_COMPONENT_MAPPING_LINEAR_API CenterOfMassMapping< Rigid3Types, Vec3Types >; +template class SOFA_COMPONENT_MAPPING_LINEAR_API CenterOfMassMapping< Rigid2Types, Vec2Types >; } // namespace sofa::component::mapping::linear diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMapping.h index 74abbcd26f04..ceadd54edb5f 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMapping.h @@ -108,7 +108,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_MAPPING_CENTEROFMASSMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_CENTEROFMASSMAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API CenterOfMassMapping< sofa::defaulttype::Rigid3Types, sofa::defaulttype::Vec3Types >; extern template class SOFA_COMPONENT_MAPPING_LINEAR_API CenterOfMassMapping< sofa::defaulttype::Rigid2Types, sofa::defaulttype::Vec2Types >; #endif diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMulti2Mapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMulti2Mapping.h index 3e15b9eef4a3..98ecebd089c5 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMulti2Mapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMulti2Mapping.h @@ -125,7 +125,7 @@ class CenterOfMassMulti2Mapping : public core::Multi2Mapping double invTotalMass; }; -#if !defined(SOFA_COMPONENT_MAPPING_CENTEROFMASSMULTI2MAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_CENTEROFMASSMULTI2MAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API CenterOfMassMulti2Mapping< defaulttype::Vec3Types, defaulttype::Rigid3Types, defaulttype::Vec3Types >; #endif diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMultiMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMultiMapping.h index b6fb86eed41a..8834b5c8664b 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMultiMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/CenterOfMassMultiMapping.h @@ -103,7 +103,7 @@ class CenterOfMassMultiMapping : public core::MultiMapping double invTotalMass; }; -#if !defined(SOFA_COMPONENT_MAPPING_CENTEROFMASSMULTIMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_CENTEROFMASSMULTIMAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API CenterOfMassMultiMapping< defaulttype::Vec3Types, defaulttype::Vec3Types >; extern template class SOFA_COMPONENT_MAPPING_LINEAR_API CenterOfMassMultiMapping< defaulttype::Rigid3Types, defaulttype::Rigid3Types >; extern template class SOFA_COMPONENT_MAPPING_LINEAR_API CenterOfMassMultiMapping< defaulttype::Rigid3Types, defaulttype::Vec3Types >; diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/DeformableOnRigidFrameMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/DeformableOnRigidFrameMapping.h index ab6a09427c47..6c82cdf2e659 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/DeformableOnRigidFrameMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/DeformableOnRigidFrameMapping.h @@ -173,7 +173,7 @@ class DeformableOnRigidFrameMapping : public core::Multi2Mapping; #endif diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/IdentityMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/IdentityMapping.h index 11460e7673f7..215551abcfc4 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/IdentityMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/IdentityMapping.h @@ -124,7 +124,7 @@ class IdentityMapping : public core::Mapping }; -#if !defined(SOFA_COMPONENT_MAPPING_IDENTITYMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_IDENTITYMAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API IdentityMapping< defaulttype::Vec3Types, defaulttype::Vec3Types >; extern template class SOFA_COMPONENT_MAPPING_LINEAR_API IdentityMapping< defaulttype::Vec2Types, defaulttype::Vec2Types >; diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/IdentityMultiMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/IdentityMultiMapping.h index 6f9d05751acd..f81b48548e9e 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/IdentityMultiMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/IdentityMultiMapping.h @@ -87,7 +87,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_MAPPING_IDENTITYMULTIMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_IDENTITYMULTIMAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API IdentityMultiMapping< defaulttype::Vec3Types, defaulttype::Vec3Types >; extern template class SOFA_COMPONENT_MAPPING_LINEAR_API IdentityMultiMapping< defaulttype::Rigid3Types, defaulttype::Rigid3Types >; diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/LineSetSkinningMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/LineSetSkinningMapping.h index b8581f643a65..1674841785be 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/LineSetSkinningMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/LineSetSkinningMapping.h @@ -180,7 +180,7 @@ class LineSetSkinningMapping : public core::Mapping type::vector > neighborhood; }; -#if !defined(SOFA_COMPONENT_MAPPING_LINESETSKINNINGMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_LINESETSKINNINGMAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API LineSetSkinningMapping< defaulttype::Rigid3Types, defaulttype::Vec3Types >; diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/Mesh2PointMechanicalMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/Mesh2PointMechanicalMapping.h index 1de96469e05d..df1cc7ca2b76 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/Mesh2PointMechanicalMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/Mesh2PointMechanicalMapping.h @@ -83,7 +83,7 @@ class Mesh2PointMechanicalMapping : public core::Mapping -#if !defined(SOFA_COMPONENT_MAPPING_MESH2POINTMECHANICALMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_MESH2POINTMECHANICALMAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API Mesh2PointMechanicalMapping< defaulttype::Vec3Types, defaulttype::Vec3Types >; #endif diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SimpleTesselatedTetraMechanicalMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SimpleTesselatedTetraMechanicalMapping.h index 3f604f336c44..134337daac3b 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SimpleTesselatedTetraMechanicalMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SimpleTesselatedTetraMechanicalMapping.h @@ -86,7 +86,7 @@ class SimpleTesselatedTetraMechanicalMapping : public core::Mapping core::topology::BaseMeshTopology* outputTopo; }; -#if !defined(SOFA_COMPONENT_MAPPING_SIMPLETESSELATEDTETRAMECHANICALMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_SIMPLETESSELATEDTETRAMECHANICALMAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API SimpleTesselatedTetraMechanicalMapping< defaulttype::Vec3Types, defaulttype::Vec3Types >; diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SkinningMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SkinningMapping.h index f607cadb9a35..efc2709d6ef1 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SkinningMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SkinningMapping.h @@ -122,7 +122,7 @@ class SkinningMapping : public core::Mapping }; -#if !defined(SOFA_COMPONENT_MAPPING_SKINNINGMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_SKINNINGMAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API SkinningMapping< sofa::defaulttype::Rigid3Types, sofa::defaulttype::Vec3Types >; #endif // !defined(SOFA_COMPONENT_MAPPING_SKINNINGMAPPING_CPP) diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SubsetMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SubsetMapping.h index 8e720ef78808..5b6fd86152df 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SubsetMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SubsetMapping.h @@ -132,7 +132,7 @@ class SubsetMapping : public core::Mapping bool updateJ; }; -#if !defined(SOFA_COMPONENT_MAPPING_SUBSETMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_SUBSETMAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API SubsetMapping< sofa::defaulttype::Vec3Types, sofa::defaulttype::Vec3Types >; extern template class SOFA_COMPONENT_MAPPING_LINEAR_API SubsetMapping< sofa::defaulttype::Vec1Types, sofa::defaulttype::Vec1Types >; diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SubsetMultiMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SubsetMultiMapping.h index a2e72c00f82a..13dca1f6631f 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SubsetMultiMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SubsetMultiMapping.h @@ -101,7 +101,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_MAPPING_SUBSETMULTIMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_SUBSETMULTIMAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API SubsetMultiMapping< defaulttype::Vec3Types, defaulttype::Vec3Types >; extern template class SOFA_COMPONENT_MAPPING_LINEAR_API SubsetMultiMapping< defaulttype::Vec2Types, defaulttype::Vec2Types >; extern template class SOFA_COMPONENT_MAPPING_LINEAR_API SubsetMultiMapping< defaulttype::Vec1Types, defaulttype::Vec1Types >; diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/TubularMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/TubularMapping.h index cbafd7bd2806..e5f6ec38861f 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/TubularMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/TubularMapping.h @@ -100,7 +100,7 @@ class TubularMapping : public core::Mapping }; -#if !defined(SOFA_COMPONENT_MAPPING_TUBULARMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_TUBULARMAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_LINEAR_API TubularMapping< defaulttype::Rigid3Types, defaulttype::Vec3Types >; diff --git a/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceFromTargetMapping.h b/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceFromTargetMapping.h index e37391af07cd..8f9413e41143 100644 --- a/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceFromTargetMapping.h +++ b/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceFromTargetMapping.h @@ -136,7 +136,7 @@ class DistanceFromTargetMapping : public core::Mapping, public BaseDi }; -#if !defined(SOFA_COMPONENT_MAPPING_DistanceFromTargetMapping_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_DistanceFromTargetMapping_CPP) extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API DistanceFromTargetMapping< defaulttype::Vec3Types, defaulttype::Vec1Types >; extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API DistanceFromTargetMapping< defaulttype::Vec1Types, defaulttype::Vec1Types >; extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API DistanceFromTargetMapping< defaulttype::Rigid3Types, defaulttype::Vec1Types >; diff --git a/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceMapping.h b/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceMapping.h index e35efe312621..ce20e9c62fe6 100644 --- a/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceMapping.h +++ b/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceMapping.h @@ -133,7 +133,7 @@ class DistanceMapping : public core::Mapping, public NonLinearMapping -#if !defined(SOFA_COMPONENT_MAPPING_DistanceMapping_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_DistanceMapping_CPP) extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API DistanceMapping< defaulttype::Vec3Types, defaulttype::Vec1Types >; extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API DistanceMapping< defaulttype::Rigid3Types, defaulttype::Vec1Types >; #endif diff --git a/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceMultiMapping.h b/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceMultiMapping.h index fb50c3cbed74..f2836695ac8c 100644 --- a/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceMultiMapping.h +++ b/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceMultiMapping.h @@ -218,7 +218,7 @@ class DistanceMultiMapping : public core::MultiMapping, public NonLin }; -#if !defined(SOFA_COMPONENT_MAPPING_DistanceMultiMapping_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_DistanceMultiMapping_CPP) extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API DistanceMultiMapping< defaulttype::Vec3Types, defaulttype::Vec1Types >; extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API DistanceMultiMapping< defaulttype::Rigid3Types, defaulttype::Vec1Types >; #endif diff --git a/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/RigidMapping.h b/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/RigidMapping.h index 889c20e147a4..66b46fcddab1 100644 --- a/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/RigidMapping.h +++ b/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/RigidMapping.h @@ -194,7 +194,7 @@ void RigidMapping< sofa::defaulttype::Rigid2Types, sofa::defaulttype::Vec2Types template<> const linearalgebra::BaseMatrix* RigidMapping< sofa::defaulttype::Rigid2Types, sofa::defaulttype::Vec2Types >::getK(); -#if !defined(SOFA_COMPONENT_MAPPING_RIGIDMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_RIGIDMAPPING_CPP) extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API RigidMapping< sofa::defaulttype::Rigid3Types, sofa::defaulttype::Vec3Types >; extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API RigidMapping< sofa::defaulttype::Rigid3Types, sofa::defaulttype::Rigid3Types >; extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API RigidMapping< sofa::defaulttype::Rigid2Types, sofa::defaulttype::Vec2Types >; diff --git a/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/SquareDistanceMapping.h b/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/SquareDistanceMapping.h index f9f077352f25..017f9123a8c1 100644 --- a/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/SquareDistanceMapping.h +++ b/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/SquareDistanceMapping.h @@ -129,7 +129,7 @@ class SquareDistanceMapping : public core::Mapping, public NonLinearM -#if !defined(SOFA_COMPONENT_MAPPING_SquareDistanceMapping_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_SquareDistanceMapping_CPP) extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API SquareDistanceMapping< defaulttype::Vec3Types, defaulttype::Vec1Types >; extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API SquareDistanceMapping< defaulttype::Rigid3Types, defaulttype::Vec1Types >; #endif diff --git a/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/SquareMapping.h b/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/SquareMapping.h index ffe091693bf6..161037cbb244 100644 --- a/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/SquareMapping.h +++ b/Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/SquareMapping.h @@ -102,7 +102,7 @@ class SquareMapping : public core::Mapping, public NonLinearMappingDa -#if !defined(SOFA_COMPONENT_MAPPING_SquareMapping_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_SquareMapping_CPP) extern template class SOFA_COMPONENT_MAPPING_NONLINEAR_API SquareMapping< defaulttype::Vec1Types, defaulttype::Vec1Types >; diff --git a/Sofa/Component/Mass/src/sofa/component/mass/DiagonalMass.h b/Sofa/Component/Mass/src/sofa/component/mass/DiagonalMass.h index c040add8fcbb..6f382372404c 100644 --- a/Sofa/Component/Mass/src/sofa/component/mass/DiagonalMass.h +++ b/Sofa/Component/Mass/src/sofa/component/mass/DiagonalMass.h @@ -383,7 +383,7 @@ type::Vec6 DiagonalMass::getMomentum ( const core::Mec -#if !defined(SOFA_COMPONENT_MASS_DIAGONALMASS_CPP) +#if !defined(SOFA_COMPONENT_MASS_DIAGONALMASS_CPP) extern template class SOFA_COMPONENT_MASS_API DiagonalMass; extern template class SOFA_COMPONENT_MASS_API DiagonalMass; extern template class SOFA_COMPONENT_MASS_API DiagonalMass; diff --git a/Sofa/Component/Mass/src/sofa/component/mass/MeshMatrixMass.h b/Sofa/Component/Mass/src/sofa/component/mass/MeshMatrixMass.h index f71ab8d03a83..195efd7a95c8 100644 --- a/Sofa/Component/Mass/src/sofa/component/mass/MeshMatrixMass.h +++ b/Sofa/Component/Mass/src/sofa/component/mass/MeshMatrixMass.h @@ -402,7 +402,7 @@ class MeshMatrixMass : public core::behavior::Mass typename sofa::core::behavior::MechanicalState::SPtr m_geometryState; }; -#if !defined(SOFA_COMPONENT_MASS_MESHMATRIXMASS_CPP) +#if !defined(SOFA_COMPONENT_MASS_MESHMATRIXMASS_CPP) extern template class SOFA_COMPONENT_MASS_API MeshMatrixMass; extern template class SOFA_COMPONENT_MASS_API MeshMatrixMass; extern template class SOFA_COMPONENT_MASS_API MeshMatrixMass; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/ConicalForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/ConicalForceField.h index 8fb4b413d3fa..70aae7726eac 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/ConicalForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/ConicalForceField.h @@ -121,7 +121,7 @@ class ConicalForceField : public core::behavior::ForceField }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_CONICALFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_CONICALFORCEFIELD_CPP) extern template class SOFA_COMPONENT_MECHANICALLOAD_API ConicalForceField; #endif diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/DiagonalVelocityDampingForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/DiagonalVelocityDampingForceField.h index 652a0bfec876..c39b41bcb8b9 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/DiagonalVelocityDampingForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/DiagonalVelocityDampingForceField.h @@ -71,7 +71,7 @@ class DiagonalVelocityDampingForceField : public core::behavior::ForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API DiagonalVelocityDampingForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API DiagonalVelocityDampingForceField; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EdgePressureForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EdgePressureForceField.h index 11a16ee92f06..782bca98e1c6 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EdgePressureForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EdgePressureForceField.h @@ -128,7 +128,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_EDGEPRESSUREFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_EDGEPRESSUREFORCEFIELD_CPP) extern template class SOFA_COMPONENT_MECHANICALLOAD_API EdgePressureForceField; #endif // !defined(SOFA_COMPONENT_FORCEFIELD_EDGEPRESSUREFORCEFIELD_CPP) diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.h index ab51683cfd78..7bf769b9c3a3 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.h @@ -139,7 +139,7 @@ class EllipsoidForceField : public core::behavior::ForceField }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_ELLIPSOIDFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_ELLIPSOIDFORCEFIELD_CPP) extern template class SOFA_COMPONENT_MECHANICALLOAD_API EllipsoidForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API EllipsoidForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API EllipsoidForceField; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/InteractionEllipsoidForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/InteractionEllipsoidForceField.h index c61543f8979b..d73706574af7 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/InteractionEllipsoidForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/InteractionEllipsoidForceField.h @@ -167,7 +167,7 @@ class InteractionEllipsoidForceField : public core::behavior::MixedInteractionFo } vars; }; -#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_INTERACTIONELLIPSOIDFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_INTERACTIONELLIPSOIDFORCEFIELD_CPP) extern template class InteractionEllipsoidForceField; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/LinearForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/LinearForceField.h index a09129ce9f8e..fc522be67de7 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/LinearForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/LinearForceField.h @@ -138,7 +138,7 @@ SReal SOFA_COMPONENT_MECHANICALLOAD_API LinearForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API LinearForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API LinearForceField; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/OscillatingTorsionPressureForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/OscillatingTorsionPressureForceField.h index ec8d35122d78..cf76aa43a352 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/OscillatingTorsionPressureForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/OscillatingTorsionPressureForceField.h @@ -142,7 +142,7 @@ protected : sofa::core::topology::BaseMeshTopology* m_topology; ///< Pointer to the current topology }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_OSCILLATINGTORSIONPRESSUREFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_OSCILLATINGTORSIONPRESSUREFORCEFIELD_CPP) extern template class SOFA_COMPONENT_MECHANICALLOAD_API OscillatingTorsionPressureForceField; #endif // !defined(SOFA_COMPONENT_FORCEFIELD_OSCILLATINGTORSIONPRESSUREFORCEFIELD_CPP) diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/PlaneForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/PlaneForceField.h index 9dd815129454..c338329b09e7 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/PlaneForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/PlaneForceField.h @@ -123,7 +123,7 @@ class PlaneForceField : public core::behavior::ForceField }; -#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_PLANEFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_PLANEFORCEFIELD_CPP) extern template class SOFA_COMPONENT_MECHANICALLOAD_API PlaneForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API PlaneForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API PlaneForceField; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/QuadPressureForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/QuadPressureForceField.h index c24e61516645..30b0065f604a 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/QuadPressureForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/QuadPressureForceField.h @@ -138,7 +138,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_QUADPRESSUREFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_QUADPRESSUREFORCEFIELD_CPP) extern template class SOFA_COMPONENT_MECHANICALLOAD_API QuadPressureForceField; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/SphereForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/SphereForceField.h index 0fafb2f214ef..8661fa1c320f 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/SphereForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/SphereForceField.h @@ -118,7 +118,7 @@ class SphereForceField : public core::behavior::ForceField void draw(const core::visual::VisualParams* vparams) override; }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_SPHEREFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_SPHEREFORCEFIELD_CPP) extern template class SOFA_COMPONENT_MECHANICALLOAD_API SphereForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API SphereForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API SphereForceField; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/SurfacePressureForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/SurfacePressureForceField.h index e5f59b30ec29..90382808928b 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/SurfacePressureForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/SurfacePressureForceField.h @@ -170,7 +170,7 @@ template <> void SurfacePressureForceField::verifyDerivative(VecDeriv& v_plus, VecDeriv& v, VecVec3DerivValues& DVval, VecVec3DerivIndices& DVind, const VecDeriv& Din); -#if !defined(SOFA_COMPONENT_FORCEFIELD_SURFACEPRESSUREFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_SURFACEPRESSUREFORCEFIELD_CPP) extern template class SOFA_COMPONENT_MECHANICALLOAD_API SurfacePressureForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API SurfacePressureForceField; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/TaitSurfacePressureForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/TaitSurfacePressureForceField.h index 9f891bc6cda2..179d8db7269a 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/TaitSurfacePressureForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/TaitSurfacePressureForceField.h @@ -134,7 +134,7 @@ class TaitSurfacePressureForceField : public core::behavior::ForceField; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/TorsionForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/TorsionForceField.h index 5669e8395b9b..580a2e4d401b 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/TorsionForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/TorsionForceField.h @@ -98,7 +98,7 @@ template<> void TorsionForceField::addDForce(const core::MechanicalParams *mparams, DataVecDeriv &df, const DataVecDeriv &dx); -#if !defined(SOFA_COMPONENT_FORCEFIELD_TORSIONFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_TORSIONFORCEFIELD_CPP) extern template class SOFA_COMPONENT_MECHANICALLOAD_API TorsionForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API TorsionForceField; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/UniformVelocityDampingForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/UniformVelocityDampingForceField.h index 4e8aedf7f0e4..42526e91ba2f 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/UniformVelocityDampingForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/UniformVelocityDampingForceField.h @@ -72,7 +72,7 @@ class UniformVelocityDampingForceField : public core::behavior::ForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API UniformVelocityDampingForceField; extern template class SOFA_COMPONENT_MECHANICALLOAD_API UniformVelocityDampingForceField; diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/BeamFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/BeamFEMForceField.h index 8e85b935b21b..79e67e6ed1fd 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/BeamFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/BeamFEMForceField.h @@ -197,7 +197,7 @@ class BeamFEMForceField : public ForceField void applyStiffnessLarge( VecDeriv& f, const VecDeriv& x, int i, Index a, Index b, SReal fact=1.0); }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_BEAMFEMFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_BEAMFEMFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API BeamFEMForceField; #endif diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/FastTetrahedralCorotationalForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/FastTetrahedralCorotationalForceField.h index d534e341d9a3..9490d42fc9e9 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/FastTetrahedralCorotationalForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/FastTetrahedralCorotationalForceField.h @@ -203,7 +203,7 @@ protected : ExtraData m_data; }; -#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_FASTTETRAHEDRALCOROTATIONALFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_FASTTETRAHEDRALCOROTATIONALFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API FastTetrahedralCorotationalForceField; #endif diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedralFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedralFEMForceField.h index 7c289934407c..9f65def4a083 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedralFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedralFEMForceField.h @@ -203,7 +203,7 @@ class HexahedralFEMForceField : virtual public core::behavior::ForceField _coef; ///< coef of each vertices to compute the strain stress matrix }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_HEXAHEDRALFEMFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_HEXAHEDRALFEMFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API HexahedralFEMForceField; #endif diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedralFEMForceFieldAndMass.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedralFEMForceFieldAndMass.h index 60583d0f1300..a8b34db740bb 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedralFEMForceFieldAndMass.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedralFEMForceFieldAndMass.h @@ -132,7 +132,7 @@ class HexahedralFEMForceFieldAndMass : virtual public sofa::core::behavior::Mass core::topology::PointData > _lumpedMasses; ///< masses per particle computed by lumping mass matrices }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_HEXAHEDRALFEMFORCEFIELDANDMASS_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_HEXAHEDRALFEMFORCEFIELDANDMASS_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API HexahedralFEMForceFieldAndMass; #endif diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.h index fd127903c46f..536c7f451726 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.h @@ -225,7 +225,7 @@ class HexahedronFEMForceField : virtual public core::behavior::ForceField; #endif diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceFieldAndMass.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceFieldAndMass.h index ce1c809dfd65..424c67cfd541 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceFieldAndMass.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceFieldAndMass.h @@ -141,7 +141,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_HEXAHEDRONFEMFORCEFIELDANDMASS_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_HEXAHEDRONFEMFORCEFIELDANDMASS_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API HexahedronFEMForceFieldAndMass< defaulttype::Vec3Types >; #endif diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/QuadBendingFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/QuadBendingFEMForceField.h index fae59ed85bf7..a1e9e98432da 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/QuadBendingFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/QuadBendingFEMForceField.h @@ -230,7 +230,7 @@ protected : SingleLink, sofa::core::topology::BaseMeshTopology, BaseLink::FLAG_STOREPATH | BaseLink::FLAG_STRONGLINK> l_topology; }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_QUADBENDINGFEMFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_QUADBENDINGFEMFORCEFIELD_CPP) extern template class SOFA_MISC_FEM_API QuadBendingFEMForceField; diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedralCorotationalFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedralCorotationalFEMForceField.h index b60f9a31da0b..dae0e45aa19e 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedralCorotationalFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedralCorotationalFEMForceField.h @@ -246,7 +246,7 @@ class TetrahedralCorotationalFEMForceField : public core::behavior::ForceField; diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangleFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangleFEMForceField.h index 3d5429b06a7f..8375798ff654 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangleFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangleFEMForceField.h @@ -169,7 +169,7 @@ class TriangleFEMForceField : public core::behavior::ForceField }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGLEFEMFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGLEFEMFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API TriangleFEMForceField; diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularAnisotropicFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularAnisotropicFEMForceField.h index b0573313e923..2228ce781db5 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularAnisotropicFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularAnisotropicFEMForceField.h @@ -100,7 +100,7 @@ class TriangularAnisotropicFEMForceField : public TriangularFEMForceField; #endif diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceField.h index 6b9cb402ecb7..c82da9975318 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceField.h @@ -300,7 +300,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGULARFEMFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGULARFEMFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API TriangularFEMForceField; diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceFieldOptim.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceFieldOptim.h index c3ad86269281..55d851e60b4e 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceFieldOptim.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceFieldOptim.h @@ -259,7 +259,7 @@ class TriangularFEMForceFieldOptim : public core::behavior::ForceField; diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/StandardTetrahedralFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/StandardTetrahedralFEMForceField.h index 8bd25a20a2fa..277c39ae370e 100644 --- a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/StandardTetrahedralFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/StandardTetrahedralFEMForceField.h @@ -215,7 +215,7 @@ public : }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_STANDARDTETRAHEDRALFEMFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_STANDARDTETRAHEDRALFEMFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API StandardTetrahedralFEMForceField; diff --git a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/TetrahedronHyperelasticityFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/TetrahedronHyperelasticityFEMForceField.h index 6b336716d37b..0cec0862acd3 100644 --- a/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/TetrahedronHyperelasticityFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/HyperElastic/src/sofa/component/solidmechanics/fem/hyperelastic/TetrahedronHyperelasticityFEMForceField.h @@ -192,7 +192,7 @@ class TetrahedronHyperelasticityFEMForceField : public core::behavior::ForceFiel void instantiateMaterial(); }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_TETRAHEDRONHYPERELASTICITYFEMFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_TETRAHEDRONHYPERELASTICITYFEMFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_HYPERELASTIC_API TetrahedronHyperelasticityFEMForceField; #endif // !defined(SOFA_COMPONENT_FORCEFIELD_TETRAHEDRONHYPERELASTICITYFEMFORCEFIELD_CPP) diff --git a/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/HexahedronCompositeFEMForceFieldAndMass.h b/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/HexahedronCompositeFEMForceFieldAndMass.h index a3b6294b6dfe..acfd7af835ff 100644 --- a/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/HexahedronCompositeFEMForceFieldAndMass.h +++ b/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/HexahedronCompositeFEMForceFieldAndMass.h @@ -142,7 +142,7 @@ class HexahedronCompositeFEMForceFieldAndMass : public NonUniformHexahedronFEMFo }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_HEXAHEDRONCOMPOSITEFEMFORCEFIELDANDMASS_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_HEXAHEDRONCOMPOSITEFEMFORCEFIELDANDMASS_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_NONUNIFORM_API HexahedronCompositeFEMForceFieldAndMass; #endif diff --git a/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/HexahedronCompositeFEMMapping.h b/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/HexahedronCompositeFEMMapping.h index f3afcfeed690..e103b4ea162c 100644 --- a/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/HexahedronCompositeFEMMapping.h +++ b/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/HexahedronCompositeFEMMapping.h @@ -144,7 +144,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_MAPPING_HEXAHEDRONCOMPOSITEFEMMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_HEXAHEDRONCOMPOSITEFEMMAPPING_CPP) extern template class HexahedronCompositeFEMMapping< core::Mapping< defaulttype::Vec3Types, defaulttype::Vec3Types > >; diff --git a/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/NonUniformHexahedralFEMForceFieldAndMass.h b/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/NonUniformHexahedralFEMForceFieldAndMass.h index 4531e76ecb3a..e42b5b48d338 100644 --- a/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/NonUniformHexahedralFEMForceFieldAndMass.h +++ b/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/NonUniformHexahedralFEMForceFieldAndMass.h @@ -195,7 +195,7 @@ class NonUniformHexahedralFEMForceFieldAndMass : virtual public component::solid virtual void computeCorrection( ElementMass& ) {} ///< Limit the conditioning number of each mbkMatrix as defined by maxConditioning (in derived classes). }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_NONUNIFORMHEXAHEDRALFEMFORCEFIELDANDMASS_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_NONUNIFORMHEXAHEDRALFEMFORCEFIELDANDMASS_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_NONUNIFORM_API NonUniformHexahedralFEMForceFieldAndMass; #endif diff --git a/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/NonUniformHexahedronFEMForceFieldAndMass.h b/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/NonUniformHexahedronFEMForceFieldAndMass.h index 7a15ee4bc638..06371be7b717 100644 --- a/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/NonUniformHexahedronFEMForceFieldAndMass.h +++ b/Sofa/Component/SolidMechanics/FEM/NonUniform/src/sofa/component/solidmechanics/fem/nonuniform/NonUniformHexahedronFEMForceFieldAndMass.h @@ -118,7 +118,7 @@ class NonUniformHexahedronFEMForceFieldAndMass : virtual public component::solid }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_NONUNIFORMHEXAHEDRONFEMFORCEFIELDANDMASS_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_NONUNIFORMHEXAHEDRONFEMFORCEFIELDANDMASS_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_NONUNIFORM_API NonUniformHexahedronFEMForceFieldAndMass; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/AngularSpringForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/AngularSpringForceField.h index d0eb88b82851..af532c9d9cb3 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/AngularSpringForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/AngularSpringForceField.h @@ -100,7 +100,7 @@ protected : VecReal k; }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_AngularSpringForceField_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_AngularSpringForceField_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API AngularSpringForceField; #endif diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/FastTriangularBendingSprings.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/FastTriangularBendingSprings.h index 4ff2cf26f916..fd0f98839ecf 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/FastTriangularBendingSprings.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/FastTriangularBendingSprings.h @@ -210,7 +210,7 @@ class FastTriangularBendingSprings : public core::behavior::ForceField< _DataTyp SReal m_potentialEnergy; }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_FastTriangularBendingSprings_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_FastTriangularBendingSprings_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API FastTriangularBendingSprings; #endif // !defined(SOFA_COMPONENT_FORCEFIELD_FastTriangularBendingSprings_CPP) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/FrameSpringForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/FrameSpringForceField.h index d0e4d397c367..f1117be72980 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/FrameSpringForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/FrameSpringForceField.h @@ -205,7 +205,7 @@ class FrameSpringForceField : public core::behavior::PairInteractionForceField; #endif diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/GearSpringForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/GearSpringForceField.h index 4b2db5cb5937..908526a3ba8f 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/GearSpringForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/GearSpringForceField.h @@ -299,7 +299,7 @@ class GearSpringForceField : public core::behavior::PairInteractionForceField; extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API GearSpringForceField; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/JointSpring.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/JointSpring.h index ed949d2cf568..71c17d479785 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/JointSpring.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/JointSpring.h @@ -212,7 +212,7 @@ class JointSpring } }; -#if !defined(SOFA_JOINTSPRING_CPP) +#if !defined(SOFA_JOINTSPRING_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API JointSpring; #endif diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/MeshSpringForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/MeshSpringForceField.h index d884be777b4a..221701c66531 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/MeshSpringForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/MeshSpringForceField.h @@ -148,7 +148,7 @@ class MeshSpringForceField : public virtual StiffSpringForceField void draw(const core::visual::VisualParams* vparams) override; }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_MESHSPRINGFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_MESHSPRINGFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API MeshSpringForceField; extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API MeshSpringForceField; extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API MeshSpringForceField; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadBendingSprings.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadBendingSprings.h index 07aff098b473..08221baa1034 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadBendingSprings.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadBendingSprings.h @@ -69,7 +69,7 @@ class QuadBendingSprings : public StiffSpringForceField }; -#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_QUADBENDINGSPRINGS_CPP) +#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_QUADBENDINGSPRINGS_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API QuadBendingSprings; extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API QuadBendingSprings; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.h index 329e7b090978..80485ee7f5c3 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.h @@ -186,7 +186,7 @@ class QuadularBendingSprings : public core::behavior::ForceField }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_QUADULARBENDINGSPRINGS_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_QUADULARBENDINGSPRINGS_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API QuadularBendingSprings; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RegularGridSpringForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RegularGridSpringForceField.h index 839043cd13a1..585277b30788 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RegularGridSpringForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RegularGridSpringForceField.h @@ -119,7 +119,7 @@ class RegularGridSpringForceField : public StiffSpringForceField protected: topology::container::grid::RegularGridTopology* topology; }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_REGULARGRIDSPRINGFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_REGULARGRIDSPRINGFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API RegularGridSpringForceField; extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API RegularGridSpringForceField; extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API RegularGridSpringForceField; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RepulsiveSpringForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RepulsiveSpringForceField.h index e0d9b6509f1b..8022b54c82ae 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RepulsiveSpringForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RepulsiveSpringForceField.h @@ -62,7 +62,7 @@ class RepulsiveSpringForceField : public StiffSpringForceField SReal getPotentialEnergy(const sofa::core::MechanicalParams*, const DataVecCoord&, const DataVecCoord& ) const override; }; -#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_REPULSIVESPRINGFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_REPULSIVESPRINGFORCEFIELD_CPP) extern template class RepulsiveSpringForceField; extern template class RepulsiveSpringForceField; extern template class RepulsiveSpringForceField; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RestShapeSpringsForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RestShapeSpringsForceField.h index b78684ab417e..c08facb46d4a 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RestShapeSpringsForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/RestShapeSpringsForceField.h @@ -139,7 +139,7 @@ private : bool useRestMState{}; /// An external MechanicalState is used as rest reference. }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_RESTSHAPESPRINGSFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_RESTSHAPESPRINGSFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API RestShapeSpringsForceField; extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API RestShapeSpringsForceField; extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API RestShapeSpringsForceField; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.h index f96ae882be1b..a58567990a6e 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/SpringForceField.h @@ -200,7 +200,7 @@ class SpringForceField : public core::behavior::PairInteractionForceField; extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API SpringForceField; extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API SpringForceField; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangleBendingSprings.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangleBendingSprings.h index 4b56b4469809..218e6298336b 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangleBendingSprings.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangleBendingSprings.h @@ -66,7 +66,7 @@ class TriangleBendingSprings : public StiffSpringForceField }; -#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_TRIANGLEBENDINGSPRINGS_CPP) +#if !defined(SOFA_COMPONENT_INTERACTIONFORCEFIELD_TRIANGLEBENDINGSPRINGS_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API TriangleBendingSprings; extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API TriangleBendingSprings; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.h index b72a86b5cf7b..1c4a57cea868 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.h @@ -167,7 +167,7 @@ class TriangularBendingSprings : public core::behavior::ForceField sofa::core::topology::BaseMeshTopology* m_topology; }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGULARBENDINGSPRINGS_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGULARBENDINGSPRINGS_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API TriangularBendingSprings; #endif // !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGULARBENDINGSPRINGS_CPP) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBiquadraticSpringsForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBiquadraticSpringsForceField.h index f071eef2674f..309e81b7b886 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBiquadraticSpringsForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBiquadraticSpringsForceField.h @@ -208,7 +208,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGULARBIQUADRATICSPRINGSFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGULARBIQUADRATICSPRINGSFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API TriangularBiquadraticSpringsForceField; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularQuadraticSpringsForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularQuadraticSpringsForceField.h index 3dac35389b02..28ce37bea6bc 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularQuadraticSpringsForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularQuadraticSpringsForceField.h @@ -198,7 +198,7 @@ protected : sofa::core::topology::BaseMeshTopology* m_topology; }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGULARQUADRATICSPRINGSFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGULARQUADRATICSPRINGSFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_SPRING_API TriangularQuadraticSpringsForceField; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/VectorSpringForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/VectorSpringForceField.h index a633f6ab06ba..3b0d7cff5a08 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/VectorSpringForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/VectorSpringForceField.h @@ -179,7 +179,7 @@ class VectorSpringForceField: public core::behavior::PairInteractionForceField; #endif diff --git a/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TetrahedralTensorMassForceField.h b/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TetrahedralTensorMassForceField.h index b3a8b7b416a4..3d4590c9dd08 100644 --- a/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TetrahedralTensorMassForceField.h +++ b/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TetrahedralTensorMassForceField.h @@ -164,7 +164,7 @@ class TetrahedralTensorMassForceField : public core::behavior::ForceField; diff --git a/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TriangularTensorMassForceField.h b/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TriangularTensorMassForceField.h index 164feb006dac..4f6ef5581103 100644 --- a/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TriangularTensorMassForceField.h +++ b/Sofa/Component/SolidMechanics/TensorMass/src/sofa/component/solidmechanics/tensormass/TriangularTensorMassForceField.h @@ -170,7 +170,7 @@ protected : }; -#if !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGULARTENSORMASSFORCEFIELD_CPP) +#if !defined(SOFA_COMPONENT_FORCEFIELD_TRIANGULARTENSORMASSFORCEFIELD_CPP) extern template class SOFA_COMPONENT_SOLIDMECHANICS_TENSORMASS_API TriangularTensorMassForceField; diff --git a/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MappedObject.h b/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MappedObject.h index 835957cb4122..9a4e49000519 100644 --- a/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MappedObject.h +++ b/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MappedObject.h @@ -121,7 +121,7 @@ class MappedObject : public core::State } }; -#if !defined(SOFA_COMPONENT_CONTAINER_MAPPEDOBJECT_CPP) +#if !defined(SOFA_COMPONENT_CONTAINER_MAPPEDOBJECT_CPP) extern template class SOFA_COMPONENT_STATECONTAINER_API MappedObject; extern template class SOFA_COMPONENT_STATECONTAINER_API MappedObject; extern template class SOFA_COMPONENT_STATECONTAINER_API MappedObject; diff --git a/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MechanicalObject.h b/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MechanicalObject.h index af0728bfe2ca..3d1b0484d95d 100644 --- a/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MechanicalObject.h +++ b/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MechanicalObject.h @@ -477,7 +477,7 @@ void MechanicalObject::draw(const core::visual::Visual -#if !defined(SOFA_COMPONENT_CONTAINER_MECHANICALOBJECT_CPP) +#if !defined(SOFA_COMPONENT_CONTAINER_MECHANICALOBJECT_CPP) extern template class SOFA_COMPONENT_STATECONTAINER_API MechanicalObject; extern template class SOFA_COMPONENT_STATECONTAINER_API MechanicalObject; extern template class SOFA_COMPONENT_STATECONTAINER_API MechanicalObject; diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/DynamicSparseGridGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/DynamicSparseGridGeometryAlgorithms.h index fe77e4b22f9c..3aea8ce9a7f7 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/DynamicSparseGridGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/DynamicSparseGridGeometryAlgorithms.h @@ -71,7 +71,7 @@ template <> int SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API DynamicSparseGridGeometryAlgorithms::findNearestElementInRestPos(const Coord& pos, sofa::type::Vec3& baryC, Real& distance) const; -#if !defined(SOFA_COMPONENT_TOPOLOGY_DYNAMICSPARSEGRIDGEOMETRYALGORITHMS_CPP) +#if !defined(SOFA_COMPONENT_TOPOLOGY_DYNAMICSPARSEGRIDGEOMETRYALGORITHMS_CPP) extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API DynamicSparseGridGeometryAlgorithms; extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API DynamicSparseGridGeometryAlgorithms; #endif diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h index 8ae84f6bdc44..40d93e62be8e 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/EdgeSetGeometryAlgorithms.h @@ -186,7 +186,7 @@ class EdgeSetGeometryAlgorithms : public PointSetGeometryAlgorithms bool mustComputeBBox() const override; }; -#if !defined(SOFA_COMPONENT_TOPOLOGY_EDGESETGEOMETRYALGORITHMS_CPP) +#if !defined(SOFA_COMPONENT_TOPOLOGY_EDGESETGEOMETRYALGORITHMS_CPP) extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API EdgeSetGeometryAlgorithms; extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API EdgeSetGeometryAlgorithms; extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API EdgeSetGeometryAlgorithms; diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetGeometryAlgorithms.h index c81951f7c5e8..a611af2d89c8 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/HexahedronSetGeometryAlgorithms.h @@ -161,7 +161,7 @@ class HexahedronSetGeometryAlgorithms : public QuadSetGeometryAlgorithms; extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API HexahedronSetGeometryAlgorithms; #endif diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/NumericalIntegrationDescriptor.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/NumericalIntegrationDescriptor.h index 1cc93180b8c4..1fc27d40fab9 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/NumericalIntegrationDescriptor.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/NumericalIntegrationDescriptor.h @@ -65,7 +65,7 @@ class NumericalIntegrationDescriptor { void addQuadratureMethod(const QuadratureMethod qt, const IntegrationOrder order, QuadraturePointArray qpa); }; -#if !defined(SOFA_COMPONENT_TOPOLOGY_NUMERICALINTEGRATIONDESCRIPTOR_CPP) +#if !defined(SOFA_COMPONENT_TOPOLOGY_NUMERICALINTEGRATIONDESCRIPTOR_CPP) extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API NumericalIntegrationDescriptor; extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API NumericalIntegrationDescriptor; extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API NumericalIntegrationDescriptor; diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetGeometryAlgorithms.h index 85d5ea6d9986..bb8e4fd7105b 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/PointSetGeometryAlgorithms.h @@ -129,7 +129,7 @@ class PointSetGeometryAlgorithms : public core::topology::GeometryAlgorithms }; -#if !defined(SOFA_COMPONENT_TOPOLOGY_POINTSETGEOMETRYALGORITHMS_CPP) +#if !defined(SOFA_COMPONENT_TOPOLOGY_POINTSETGEOMETRYALGORITHMS_CPP) extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API PointSetGeometryAlgorithms; extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API PointSetGeometryAlgorithms; extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API PointSetGeometryAlgorithms; diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetGeometryAlgorithms.h index 1e6c4b2bb096..ea962fb6ff52 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/QuadSetGeometryAlgorithms.h @@ -129,7 +129,7 @@ inline Real areaProduct(const type::Vec<2,Real>& a, const type::Vec<2,Real>& b ) template< class Real> inline Real areaProduct(const type::Vec<1,Real>& , const type::Vec<1,Real>& ); -#if !defined(SOFA_COMPONENT_TOPOLOGY_QUADSETGEOMETRYALGORITHMS_CPP) +#if !defined(SOFA_COMPONENT_TOPOLOGY_QUADSETGEOMETRYALGORITHMS_CPP) extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API QuadSetGeometryAlgorithms; extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API QuadSetGeometryAlgorithms; diff --git a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.h b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.h index 7dbf8f15891c..7dc41b3fdd8f 100644 --- a/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.h +++ b/Sofa/Component/Topology/Container/Dynamic/src/sofa/component/topology/container/dynamic/TriangleSetGeometryAlgorithms.h @@ -407,7 +407,7 @@ inline Real areaProduct(const type::Vec<2,Real>& a, const type::Vec<2,Real>& b ) template< class Real> inline Real areaProduct(const type::Vec<1,Real>& , const type::Vec<1,Real>& ); -#if !defined(SOFA_COMPONENT_TOPOLOGY_TRIANGLESETGEOMETRYALGORITHMS_CPP) +#if !defined(SOFA_COMPONENT_TOPOLOGY_TRIANGLESETGEOMETRYALGORITHMS_CPP) extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API TriangleSetGeometryAlgorithms; extern template class SOFA_COMPONENT_TOPOLOGY_CONTAINER_DYNAMIC_API TriangleSetGeometryAlgorithms; #endif diff --git a/Sofa/Component/Topology/Utility/src/sofa/component/topology/utility/TopologyBoundingTrasher.h b/Sofa/Component/Topology/Utility/src/sofa/component/topology/utility/TopologyBoundingTrasher.h index 3b27007d5f32..e7c9d3210802 100644 --- a/Sofa/Component/Topology/Utility/src/sofa/component/topology/utility/TopologyBoundingTrasher.h +++ b/Sofa/Component/Topology/Utility/src/sofa/component/topology/utility/TopologyBoundingTrasher.h @@ -104,7 +104,7 @@ class SOFA_COMPONENT_TOPOLOGY_UTILITY_API TopologyBoundingTrasher: public core:: type::vector m_indicesToRemove; }; -#if !defined(SOFA_COMPONENT_TOPOLOGY_UTILITY_TOPOLOGYBOUNDINGTRASHER_CPP) +#if !defined(SOFA_COMPONENT_TOPOLOGY_UTILITY_TOPOLOGYBOUNDINGTRASHER_CPP) extern template class SOFA_COMPONENT_TOPOLOGY_UTILITY_API TopologyBoundingTrasher; #endif // !defined(SOFA_COMPONENT_TOPOLOGY_UTILITY_TOPOLOGYBOUNDINGTRASHER_CPP) diff --git a/Sofa/GL/Component/Engine/src/sofa/gl/component/engine/TextureInterpolation.h b/Sofa/GL/Component/Engine/src/sofa/gl/component/engine/TextureInterpolation.h index a16b3b02ce83..8fa1af5bc2fe 100644 --- a/Sofa/GL/Component/Engine/src/sofa/gl/component/engine/TextureInterpolation.h +++ b/Sofa/GL/Component/Engine/src/sofa/gl/component/engine/TextureInterpolation.h @@ -97,7 +97,7 @@ class TextureInterpolation : public core::DataEngine void standardLinearInterpolation(); }; -#if !defined(SOFA_COMPONENT_ENGINE_TEXTUREINTERPOLATION_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_TEXTUREINTERPOLATION_CPP) extern template class SOFA_GL_COMPONENT_ENGINE_API TextureInterpolation; extern template class SOFA_GL_COMPONENT_ENGINE_API TextureInterpolation; extern template class SOFA_GL_COMPONENT_ENGINE_API TextureInterpolation; diff --git a/Sofa/GL/src/sofa/gl/BasicShapesGL.h b/Sofa/GL/src/sofa/gl/BasicShapesGL.h index a041fc3cafd9..d7598ca36046 100644 --- a/Sofa/GL/src/sofa/gl/BasicShapesGL.h +++ b/Sofa/GL/src/sofa/gl/BasicShapesGL.h @@ -116,7 +116,7 @@ class BasicShapesGL_FakeSphere : public BasicShapesGL }; -#if !defined(SOFA_HELPER_GL_BASICSHAPESGL_CPP) +#if !defined(SOFA_HELPER_GL_BASICSHAPESGL_CPP) extern template class SOFA_GL_API BasicShapesGL_Sphere >; extern template class SOFA_GL_API BasicShapesGL_Sphere >; extern template class SOFA_GL_API BasicShapesGL_FakeSphere >; diff --git a/Sofa/GUI/Component/src/sofa/gui/component/performer/AttachBodyPerformer.h b/Sofa/GUI/Component/src/sofa/gui/component/performer/AttachBodyPerformer.h index 466bbc399d71..5e7d93d0fdee 100644 --- a/Sofa/GUI/Component/src/sofa/gui/component/performer/AttachBodyPerformer.h +++ b/Sofa/GUI/Component/src/sofa/gui/component/performer/AttachBodyPerformer.h @@ -82,7 +82,7 @@ class AttachBodyPerformer: public TInteractionPerformer core::visual::DisplayFlags flags; }; -#if !defined(SOFA_COMPONENT_COLLISION_ATTACHBODYPERFORMER_CPP) +#if !defined(SOFA_COMPONENT_COLLISION_ATTACHBODYPERFORMER_CPP) extern template class SOFA_GUI_COMPONENT_API AttachBodyPerformer; extern template class SOFA_GUI_COMPONENT_API AttachBodyPerformer; extern template class SOFA_GUI_COMPONENT_API AttachBodyPerformer; diff --git a/Sofa/GUI/Component/src/sofa/gui/component/performer/ComponentMouseInteraction.h b/Sofa/GUI/Component/src/sofa/gui/component/performer/ComponentMouseInteraction.h index ec38bd5570da..5cee747e0d55 100644 --- a/Sofa/GUI/Component/src/sofa/gui/component/performer/ComponentMouseInteraction.h +++ b/Sofa/GUI/Component/src/sofa/gui/component/performer/ComponentMouseInteraction.h @@ -86,7 +86,7 @@ protected : MouseMapping mouseMapping; }; -#if !defined(SOFA_COMPONENT_COLLISION_COMPONENTMOUSEINTERACTION_CPP) +#if !defined(SOFA_COMPONENT_COLLISION_COMPONENTMOUSEINTERACTION_CPP) extern template class SOFA_GUI_COMPONENT_API TComponentMouseInteraction; extern template class SOFA_GUI_COMPONENT_API TComponentMouseInteraction; extern template class SOFA_GUI_COMPONENT_API TComponentMouseInteraction; @@ -96,7 +96,7 @@ extern template class SOFA_GUI_COMPONENT_API TComponentMouseInteraction; diff --git a/Sofa/GUI/Component/src/sofa/gui/component/performer/ConstraintAttachBodyPerformer.h b/Sofa/GUI/Component/src/sofa/gui/component/performer/ConstraintAttachBodyPerformer.h index 29f06e8421bc..76657bbf82d8 100644 --- a/Sofa/GUI/Component/src/sofa/gui/component/performer/ConstraintAttachBodyPerformer.h +++ b/Sofa/GUI/Component/src/sofa/gui/component/performer/ConstraintAttachBodyPerformer.h @@ -98,7 +98,7 @@ class ConstraintAttachBodyPerformer: public TInteractionPerformer sofa::core::behavior::MechanicalState *mstate1, *mstate2; }; -#if !defined(SOFA_COMPONENT_COLLISION_CONSTRAINTATTACHBODYPERFORMER_CPP) +#if !defined(SOFA_COMPONENT_COLLISION_CONSTRAINTATTACHBODYPERFORMER_CPP) extern template class SOFA_GUI_COMPONENT_API ConstraintAttachBodyPerformer; #endif diff --git a/Sofa/GUI/Component/src/sofa/gui/component/performer/FixParticlePerformer.h b/Sofa/GUI/Component/src/sofa/gui/component/performer/FixParticlePerformer.h index 00ba1cf8d7a6..d3dc94bcbd8a 100644 --- a/Sofa/GUI/Component/src/sofa/gui/component/performer/FixParticlePerformer.h +++ b/Sofa/GUI/Component/src/sofa/gui/component/performer/FixParticlePerformer.h @@ -119,7 +119,7 @@ class FixParticlePerformer: public TInteractionPerformer, public FixP inline static MapTypeFunction* s_mapSupportedModels = nullptr; }; -#if !defined(SOFA_COMPONENT_COLLISION_FIXPARTICLEPERFORMER_CPP) +#if !defined(SOFA_COMPONENT_COLLISION_FIXPARTICLEPERFORMER_CPP) extern template class SOFA_GUI_COMPONENT_API FixParticlePerformer; #endif diff --git a/Sofa/GUI/Component/src/sofa/gui/component/performer/MouseInteractor.h b/Sofa/GUI/Component/src/sofa/gui/component/performer/MouseInteractor.h index ec3f1bd16fd1..9a2a15e7957f 100644 --- a/Sofa/GUI/Component/src/sofa/gui/component/performer/MouseInteractor.h +++ b/Sofa/GUI/Component/src/sofa/gui/component/performer/MouseInteractor.h @@ -120,7 +120,7 @@ class MouseInteractor : public BaseMouseInteractor MouseContainer *mouseInSofa; }; -#if !defined(SOFA_COMPONENT_COLLISION_MOUSEINTERACTOR_CPP) +#if !defined(SOFA_COMPONENT_COLLISION_MOUSEINTERACTOR_CPP) extern template class SOFA_GUI_COMPONENT_API MouseInteractor; extern template class SOFA_GUI_COMPONENT_API MouseInteractor; extern template class SOFA_GUI_COMPONENT_API MouseInteractor; diff --git a/Sofa/GUI/Component/src/sofa/gui/component/performer/RemovePrimitivePerformer.h b/Sofa/GUI/Component/src/sofa/gui/component/performer/RemovePrimitivePerformer.h index cf039c44ddf1..05cef3d25c3a 100644 --- a/Sofa/GUI/Component/src/sofa/gui/component/performer/RemovePrimitivePerformer.h +++ b/Sofa/GUI/Component/src/sofa/gui/component/performer/RemovePrimitivePerformer.h @@ -136,7 +136,7 @@ class SOFA_GUI_COMPONENT_API RemovePrimitivePerformer: public TInteraction sofa::core::topology::BaseMeshTopology* topo_curr; }; -#if !defined(SOFA_COMPONENT_COLLISION_REMOVEPRIMITIVEPERFORMER_CPP) +#if !defined(SOFA_COMPONENT_COLLISION_REMOVEPRIMITIVEPERFORMER_CPP) extern template class SOFA_GUI_COMPONENT_API RemovePrimitivePerformer; #endif diff --git a/Sofa/GUI/Component/src/sofa/gui/component/performer/SuturePointPerformer.h b/Sofa/GUI/Component/src/sofa/gui/component/performer/SuturePointPerformer.h index 7099fb155f19..b12adce22fbd 100644 --- a/Sofa/GUI/Component/src/sofa/gui/component/performer/SuturePointPerformer.h +++ b/Sofa/GUI/Component/src/sofa/gui/component/performer/SuturePointPerformer.h @@ -70,7 +70,7 @@ class SOFA_GUI_COMPONENT_API SuturePointPerformer: public TInteractionPerformer< FixObjectType *FixObject; }; -#if !defined(SOFA_COMPONENT_COLLISION_SUTUREPOINTPERFORMER_CPP) +#if !defined(SOFA_COMPONENT_COLLISION_SUTUREPOINTPERFORMER_CPP) extern template class SOFA_GUI_COMPONENT_API SuturePointPerformer; #endif diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/DataWidget.h b/Sofa/GUI/Qt/src/sofa/gui/qt/DataWidget.h index 625f02b0a4e5..1a1b272e67ce 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/DataWidget.h +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/DataWidget.h @@ -267,7 +267,7 @@ typedef sofa::helper::Factory; extern template class SOFA_CORE_API Multi2Mapping< defaulttype::Vec3Types, defaulttype::Rigid3Types, defaulttype::Vec3Types >; diff --git a/Sofa/framework/Core/src/sofa/core/State.h b/Sofa/framework/Core/src/sofa/core/State.h index 02d564aa1f14..d0b7cd052f24 100644 --- a/Sofa/framework/Core/src/sofa/core/State.h +++ b/Sofa/framework/Core/src/sofa/core/State.h @@ -159,7 +159,7 @@ class State : public virtual BaseState void computeBBox(const core::ExecParams* params, bool onlyVisible=false) override; }; -#if !defined(SOFA_CORE_STATE_CPP) +#if !defined(SOFA_CORE_STATE_CPP) extern template class SOFA_CORE_API State; extern template class SOFA_CORE_API State; extern template class SOFA_CORE_API State; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/Constraint.h b/Sofa/framework/Core/src/sofa/core/behavior/Constraint.h index 655dcd3cb061..3de988e60fd4 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/Constraint.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/Constraint.h @@ -131,7 +131,7 @@ class Constraint : public BaseConstraint, public SingleStateAccessor void storeLambda(const ConstraintParams* cParams, Data& resId, const Data& jacobian, const sofa::linearalgebra::BaseVector* lambda); }; -#if !defined(SOFA_CORE_BEHAVIOR_CONSTRAINT_CPP) +#if !defined(SOFA_CORE_BEHAVIOR_CONSTRAINT_CPP) extern template class SOFA_CORE_API Constraint; extern template class SOFA_CORE_API Constraint; extern template class SOFA_CORE_API Constraint; @@ -140,4 +140,4 @@ extern template class SOFA_CORE_API Constraint; #endif -} // namespace sofa::core::behavior \ No newline at end of file +} // namespace sofa::core::behavior diff --git a/Sofa/framework/Core/src/sofa/core/behavior/ConstraintCorrection.h b/Sofa/framework/Core/src/sofa/core/behavior/ConstraintCorrection.h index 0879cc08f7bd..cdf18249e99d 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/ConstraintCorrection.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/ConstraintCorrection.h @@ -174,7 +174,7 @@ class ConstraintCorrection : public BaseConstraintCorrection }; -#if !defined(SOFA_CORE_BEHAVIOR_CONSTRAINTCORRECTION_CPP) +#if !defined(SOFA_CORE_BEHAVIOR_CONSTRAINTCORRECTION_CPP) extern template class SOFA_CORE_API ConstraintCorrection< sofa::defaulttype::Vec3Types >; extern template class SOFA_CORE_API ConstraintCorrection< sofa::defaulttype::Vec2Types >; extern template class SOFA_CORE_API ConstraintCorrection< sofa::defaulttype::Vec1Types >; @@ -182,4 +182,4 @@ extern template class SOFA_CORE_API ConstraintCorrection< sofa::defaulttype::Rig #endif -} // namespace sofa::core::behavior \ No newline at end of file +} // namespace sofa::core::behavior diff --git a/Sofa/framework/Core/src/sofa/core/behavior/ForceField.h b/Sofa/framework/Core/src/sofa/core/behavior/ForceField.h index 3d49f3b50a9e..f73d8a29e42f 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/ForceField.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/ForceField.h @@ -223,7 +223,7 @@ class ForceField : public BaseForceField, public SingleStateAccessor }; -#if !defined(SOFA_CORE_BEHAVIOR_FORCEFIELD_CPP) +#if !defined(SOFA_CORE_BEHAVIOR_FORCEFIELD_CPP) extern template class SOFA_CORE_API ForceField; extern template class SOFA_CORE_API ForceField; extern template class SOFA_CORE_API ForceField; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/Mass.h b/Sofa/framework/Core/src/sofa/core/behavior/Mass.h index 28555fadc77f..1b8ddf04a550 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/Mass.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/Mass.h @@ -165,7 +165,7 @@ class Mass : virtual public ForceField, public BaseMass }; -#if !defined(SOFA_CORE_BEHAVIOR_MASS_CPP) +#if !defined(SOFA_CORE_BEHAVIOR_MASS_CPP) extern template class SOFA_CORE_API Mass; extern template class SOFA_CORE_API Mass; extern template class SOFA_CORE_API Mass; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/MechanicalState.h b/Sofa/framework/Core/src/sofa/core/behavior/MechanicalState.h index 27dda37c9d84..7c217c7573ac 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/MechanicalState.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/MechanicalState.h @@ -99,7 +99,7 @@ class MechanicalState : public BaseMechanicalState, public State ~MechanicalState() override {} }; -#if !defined(SOFA_CORE_BEHAVIOR_MECHANICALSTATE_CPP) +#if !defined(SOFA_CORE_BEHAVIOR_MECHANICALSTATE_CPP) extern template class SOFA_CORE_API MechanicalState; extern template class SOFA_CORE_API MechanicalState; extern template class SOFA_CORE_API MechanicalState; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionConstraint.h b/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionConstraint.h index e235d8af7860..4857eff493cc 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionConstraint.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionConstraint.h @@ -130,7 +130,7 @@ class MixedInteractionConstraint : public BaseInteractionConstraint, public Pair } }; -#if !defined(SOFA_CORE_BEHAVIOR_MIXEDINTERACTIONCONSTRAINT_CPP) +#if !defined(SOFA_CORE_BEHAVIOR_MIXEDINTERACTIONCONSTRAINT_CPP) extern template class SOFA_CORE_API MixedInteractionConstraint; extern template class SOFA_CORE_API MixedInteractionConstraint; extern template class SOFA_CORE_API MixedInteractionConstraint; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionForceField.h b/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionForceField.h index 9e535f3403cc..e9c0e65950fb 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionForceField.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/MixedInteractionForceField.h @@ -157,10 +157,9 @@ class MixedInteractionForceField : public BaseInteractionForceField, public Pair using Inherit2::getMechModel2; }; -#if !defined(SOFA_CORE_BEHAVIOR_MIXEDINTERACTIONFORCEFIELD_CPP) +#if !defined(SOFA_CORE_BEHAVIOR_MIXEDINTERACTIONFORCEFIELD_CPP) extern template class SOFA_CORE_API MixedInteractionForceField; extern template class SOFA_CORE_API MixedInteractionForceField; - extern template class SOFA_CORE_API MixedInteractionForceField; extern template class SOFA_CORE_API MixedInteractionForceField; extern template class SOFA_CORE_API MixedInteractionForceField; @@ -169,6 +168,7 @@ extern template class SOFA_CORE_API MixedInteractionForceField; extern template class SOFA_CORE_API MixedInteractionForceField; extern template class SOFA_CORE_API MixedInteractionForceField; +extern template class SOFA_CORE_API MixedInteractionForceField; extern template class SOFA_CORE_API MixedInteractionForceField; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionConstraint.h b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionConstraint.h index 690aeec72dc1..2e524f43f4e3 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionConstraint.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionConstraint.h @@ -167,7 +167,7 @@ class PairInteractionConstraint : public BaseInteractionConstraint, public PairS const sofa::linearalgebra::BaseVector* lambda); }; -#if !defined(SOFA_CORE_BEHAVIOR_PAIRINTERACTIONCONSTRAINT_CPP) +#if !defined(SOFA_CORE_BEHAVIOR_PAIRINTERACTIONCONSTRAINT_CPP) extern template class SOFA_CORE_API PairInteractionConstraint; extern template class SOFA_CORE_API PairInteractionConstraint; extern template class SOFA_CORE_API PairInteractionConstraint; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h index bddb28aa765a..063ecb8dada9 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionForceField.h @@ -220,7 +220,7 @@ class PairInteractionForceField : public BaseInteractionForceField, public PairS }; -#if !defined(SOFA_CORE_BEHAVIOR_PAIRINTERACTIONFORCEFIELD_CPP) +#if !defined(SOFA_CORE_BEHAVIOR_PAIRINTERACTIONFORCEFIELD_CPP) extern template class SOFA_CORE_API PairInteractionForceField; extern template class SOFA_CORE_API PairInteractionForceField; extern template class SOFA_CORE_API PairInteractionForceField; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionProjectiveConstraintSet.h b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionProjectiveConstraintSet.h index ea0c07ec4c5b..fa61da72190c 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionProjectiveConstraintSet.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/PairInteractionProjectiveConstraintSet.h @@ -173,7 +173,7 @@ class PairInteractionProjectiveConstraintSet : public BaseInteractionProjectiveC using Inherit2::getMechModel2; }; -#if !defined(SOFA_CORE_BEHAVIOR_PAIRINTERACTIONPROJECTIVECONSTRAINTSET_CPP) +#if !defined(SOFA_CORE_BEHAVIOR_PAIRINTERACTIONPROJECTIVECONSTRAINTSET_CPP) extern template class SOFA_CORE_API PairInteractionProjectiveConstraintSet; extern template class SOFA_CORE_API PairInteractionProjectiveConstraintSet; extern template class SOFA_CORE_API PairInteractionProjectiveConstraintSet; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/ProjectiveConstraintSet.h b/Sofa/framework/Core/src/sofa/core/behavior/ProjectiveConstraintSet.h index 026fd9304266..f6f4a853f1fc 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/ProjectiveConstraintSet.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/ProjectiveConstraintSet.h @@ -157,7 +157,7 @@ class ProjectiveConstraintSet : public BaseProjectiveConstraintSet, public Singl } }; -#if !defined(SOFA_CORE_BEHAVIOR_PROJECTIVECONSTRAINTSET_CPP) +#if !defined(SOFA_CORE_BEHAVIOR_PROJECTIVECONSTRAINTSET_CPP) extern template class SOFA_CORE_API ProjectiveConstraintSet< defaulttype::Vec6Types >; extern template class SOFA_CORE_API ProjectiveConstraintSet< defaulttype::Vec3Types >; extern template class SOFA_CORE_API ProjectiveConstraintSet< defaulttype::Vec2Types >; @@ -167,4 +167,4 @@ extern template class SOFA_CORE_API ProjectiveConstraintSet< defaulttype::Rigid2 #endif -} // namespace sofa::core::behavior \ No newline at end of file +} // namespace sofa::core::behavior diff --git a/Sofa/framework/Core/src/sofa/core/objectmodel/Data.h b/Sofa/framework/Core/src/sofa/core/objectmodel/Data.h index 8d9ec2dac6d0..eb1199ba2b5b 100644 --- a/Sofa/framework/Core/src/sofa/core/objectmodel/Data.h +++ b/Sofa/framework/Core/src/sofa/core/objectmodel/Data.h @@ -359,7 +359,7 @@ bool Data::doIsExactSameDataType(const BaseData* parent) return dynamic_cast*>(parent) != nullptr; } -#if !defined(SOFA_CORE_OBJECTMODEL_DATA_CPP) +#if !defined(SOFA_CORE_OBJECTMODEL_DATA_CPP) extern template class SOFA_CORE_API Data< std::string >; extern template class SOFA_CORE_API Data< sofa::type::vector >; extern template class SOFA_CORE_API Data< sofa::type::vector >; diff --git a/Sofa/framework/Helper/src/sofa/helper/AdvancedTimer.h b/Sofa/framework/Helper/src/sofa/helper/AdvancedTimer.h index 86124425db9a..2efb9bb8aca8 100644 --- a/Sofa/framework/Helper/src/sofa/helper/AdvancedTimer.h +++ b/Sofa/framework/Helper/src/sofa/helper/AdvancedTimer.h @@ -502,7 +502,7 @@ class SOFA_HELPER_API AdvancedTimer }; -#if !defined(SOFA_HELPER_ADVANCEDTIMER_CPP) +#if !defined(SOFA_HELPER_ADVANCEDTIMER_CPP) extern template class SOFA_HELPER_API AdvancedTimer::Id; extern template class SOFA_HELPER_API AdvancedTimer::Id; extern template class SOFA_HELPER_API AdvancedTimer::Id; diff --git a/Sofa/framework/Helper/src/sofa/helper/Polynomial_LD.h b/Sofa/framework/Helper/src/sofa/helper/Polynomial_LD.h index e8eb5299228e..28a1b34da1d1 100644 --- a/Sofa/framework/Helper/src/sofa/helper/Polynomial_LD.h +++ b/Sofa/framework/Helper/src/sofa/helper/Polynomial_LD.h @@ -235,7 +235,7 @@ inline std::istream & operator>>(std::istream & stream, Polynomial_LD -#if !defined(SOFA_HELPER_POLYNOMIAL_LD_CPP) +#if !defined(SOFA_HELPER_POLYNOMIAL_LD_CPP) extern template class SOFA_HELPER_API Monomial_LD; extern template class SOFA_HELPER_API Monomial_LD; diff --git a/Sofa/framework/Helper/src/sofa/helper/decompose.h b/Sofa/framework/Helper/src/sofa/helper/decompose.h index bd4a84b33b7c..1df4b8ae69d1 100644 --- a/Sofa/framework/Helper/src/sofa/helper/decompose.h +++ b/Sofa/framework/Helper/src/sofa/helper/decompose.h @@ -389,7 +389,7 @@ SOFA_HELPER_API inline double Decompose::zeroTolerance() return 1e-8; } -#if !defined(SOFA_BUILD_HELPER) +#if !defined(SOFA_BUILD_HELPER) extern template class SOFA_HELPER_API Decompose; extern template class SOFA_HELPER_API Decompose; #endif diff --git a/Sofa/framework/Helper/src/sofa/helper/io/Image.h b/Sofa/framework/Helper/src/sofa/helper/io/Image.h index a10c9aff8938..0364d005389a 100644 --- a/Sofa/framework/Helper/src/sofa/helper/io/Image.h +++ b/Sofa/framework/Helper/src/sofa/helper/io/Image.h @@ -154,7 +154,7 @@ class SOFA_HELPER_API Image } // namespace io -#if !defined(SOFA_HELPER_IO_IMAGE_CPP) +#if !defined(SOFA_HELPER_IO_IMAGE_CPP) extern template class SOFA_HELPER_API Factory; #endif diff --git a/Sofa/framework/Helper/src/sofa/helper/kdTree.h b/Sofa/framework/Helper/src/sofa/helper/kdTree.h index 360a5c7f4cb3..4a3b804976ca 100644 --- a/Sofa/framework/Helper/src/sofa/helper/kdTree.h +++ b/Sofa/framework/Helper/src/sofa/helper/kdTree.h @@ -88,7 +88,7 @@ protected : }; -#if !defined(SOFA_HELPER_KDTREE_CPP) +#if !defined(SOFA_HELPER_KDTREE_CPP) extern template class SOFA_HELPER_API kdTree>; extern template class SOFA_HELPER_API kdTree>; #endif diff --git a/Sofa/framework/Helper/test/system/TestPlugin/ComponentB.h b/Sofa/framework/Helper/test/system/TestPlugin/ComponentB.h index f9ee0a7b1703..572f974d2576 100644 --- a/Sofa/framework/Helper/test/system/TestPlugin/ComponentB.h +++ b/Sofa/framework/Helper/test/system/TestPlugin/ComponentB.h @@ -45,7 +45,7 @@ class SOFA_TESTPLUGIN_API ComponentB : public sofa::core::objectmodel::BaseObjec }; -#if !defined(TESTPLUGIN_COMPONENT_B_CPP) +#if !defined(TESTPLUGIN_COMPONENT_B_CPP) extern template class SOFA_TESTPLUGIN_API ComponentB; extern template class SOFA_TESTPLUGIN_API ComponentB; extern template class SOFA_TESTPLUGIN_API ComponentB; diff --git a/Sofa/framework/Simulation/Common/src/sofa/simulation/common/xml/BaseElement.h b/Sofa/framework/Simulation/Common/src/sofa/simulation/common/xml/BaseElement.h index 54ac4d5cdf4e..564f90093724 100644 --- a/Sofa/framework/Simulation/Common/src/sofa/simulation/common/xml/BaseElement.h +++ b/Sofa/framework/Simulation/Common/src/sofa/simulation/common/xml/BaseElement.h @@ -243,7 +243,7 @@ class SOFA_SIMULATION_COMMON_API BaseElement : public sofa::core::objectmodel::B namespace sofa::helper { -#if !defined(SOFA_SIMULATION_COMMON_XML_BASEELEMENT_CPP) +#if !defined(SOFA_SIMULATION_COMMON_XML_BASEELEMENT_CPP) extern template class SOFA_SIMULATION_COMMON_API Factory< std::string, sofa::simulation::xml::BaseElement, std::pair >; #endif } // namespace sofa::helper diff --git a/applications/plugins/ArticulatedSystemPlugin/src/ArticulatedSystemPlugin/ArticulatedSystemMapping.h b/applications/plugins/ArticulatedSystemPlugin/src/ArticulatedSystemPlugin/ArticulatedSystemMapping.h index 6a52a7664d30..60a734729b16 100644 --- a/applications/plugins/ArticulatedSystemPlugin/src/ArticulatedSystemPlugin/ArticulatedSystemMapping.h +++ b/applications/plugins/ArticulatedSystemPlugin/src/ArticulatedSystemPlugin/ArticulatedSystemMapping.h @@ -243,7 +243,7 @@ class ArticulatedSystemMapping : public core::Multi2Mapping void checkIndexFromRoot(); }; -#if !defined(SOFA_COMPONENT_MAPPING_ARTICULATEDSYSTEMMAPPING_CPP) +#if !defined(SOFA_COMPONENT_MAPPING_ARTICULATEDSYSTEMMAPPING_CPP) extern template class SOFA_ARTICULATEDSYSTEMPLUGIN_API ArticulatedSystemMapping< sofa::defaulttype::Vec1Types, sofa::defaulttype::Rigid3Types, sofa::defaulttype::Rigid3Types >; diff --git a/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaBaseVector.h b/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaBaseVector.h index a58647282860..77aa9dfc839e 100644 --- a/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaBaseVector.h +++ b/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaBaseVector.h @@ -293,7 +293,7 @@ template<> inline const char* CudaBaseVectord::Name() { return "CudaBaseVectord" #endif -#if !defined(SOFA_BUILD_GPU_CUDA) +#if !defined(SOFA_BUILD_GPU_CUDA) extern template class SOFA_GPU_CUDA_API CudaBaseVector< float >; #ifdef SOFA_GPU_CUDA_DOUBLE diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/statecontainer/CudaMechanicalObject.h b/applications/plugins/SofaCUDA/src/SofaCUDA/component/statecontainer/CudaMechanicalObject.h index 910e148d3aae..e82644cfc3ae 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/statecontainer/CudaMechanicalObject.h +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/statecontainer/CudaMechanicalObject.h @@ -169,6 +169,7 @@ using sofa::gpu::cuda::CudaVec3fTypes; using sofa::gpu::cuda::CudaVec3f1Types; using sofa::gpu::cuda::CudaVec6fTypes; using sofa::gpu::cuda::CudaRigid3fTypes; +using sofa::gpu::cuda::CudaRigid2fTypes; // template specialization must be in the same namespace as original namespace for GCC 4.1 @@ -179,15 +180,23 @@ extern template class SOFA_GPU_CUDA_API sofa::component::statecontainer::Mechani extern template class SOFA_GPU_CUDA_API sofa::component::statecontainer::MechanicalObject; extern template class SOFA_GPU_CUDA_API sofa::component::statecontainer::MechanicalObject; extern template class SOFA_GPU_CUDA_API sofa::component::statecontainer::MechanicalObject; +extern template class SOFA_GPU_CUDA_API sofa::component::statecontainer::MechanicalObject; #ifdef SOFA_GPU_CUDA_DOUBLE + +using sofa::gpu::cuda::CudaVec1dTypes; +using sofa::gpu::cuda::CudaVec2dTypes; using sofa::gpu::cuda::CudaVec3dTypes; using sofa::gpu::cuda::CudaVec3d1Types; using sofa::gpu::cuda::CudaVec6dTypes; using sofa::gpu::cuda::CudaRigid3dTypes; +using sofa::gpu::cuda::CudaRigid2dTypes; +extern template class SOFA_GPU_CUDA_API sofa::component::statecontainer::MechanicalObject; +extern template class SOFA_GPU_CUDA_API sofa::component::statecontainer::MechanicalObject; extern template class SOFA_GPU_CUDA_API sofa::component::statecontainer::MechanicalObject; extern template class SOFA_GPU_CUDA_API sofa::component::statecontainer::MechanicalObject; extern template class SOFA_GPU_CUDA_API sofa::component::statecontainer::MechanicalObject; extern template class SOFA_GPU_CUDA_API sofa::component::statecontainer::MechanicalObject; +extern template class SOFA_GPU_CUDA_API sofa::component::statecontainer::MechanicalObject; #endif // SOFA_GPU_CUDA_DOUBLE #endif // SOFA_GPU_CUDA_CUDAMECHANICALOBJECT_CPP diff --git a/applications/plugins/SofaMatrix/src/SofaMatrix/FillReducingOrdering.h b/applications/plugins/SofaMatrix/src/SofaMatrix/FillReducingOrdering.h index 93777df28029..1fa817348128 100644 --- a/applications/plugins/SofaMatrix/src/SofaMatrix/FillReducingOrdering.h +++ b/applications/plugins/SofaMatrix/src/SofaMatrix/FillReducingOrdering.h @@ -100,7 +100,7 @@ class FillReducingOrdering : public core::DataEngine void updateMesh(); }; -#if !defined(SOFA_COMPONENT_ENGINE_FillReducingOrdering_CPP) +#if !defined(SOFA_COMPONENT_ENGINE_FillReducingOrdering_CPP) extern template class SOFA_SOFAMATRIX_API FillReducingOrdering; #endif From d4b4d26de2f59690b4053ea3e32e4bfe846bcccf Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 11 Oct 2023 14:09:48 +0200 Subject: [PATCH 14/60] [LinearSolver.Direct] Better distribution of tasks among threads (#4220) * [LinearSolver.Direct] Better distribution of tasks among threads * Add unit test and fix --- .../linearsolver/direct/SparseLDLSolver.h | 2 + .../linearsolver/direct/SparseLDLSolver.inl | 87 +++++++++++-------- .../linearalgebra/TriangularSystemSolver.h | 25 ++++++ .../test/TriangularSystemSolver_test.cpp | 23 +++++ .../Core/src/sofa/simulation/PipelineImpl.cpp | 1 + 5 files changed, 103 insertions(+), 35 deletions(-) diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.h index e0c47e855837..44fb677240ea 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.h @@ -80,6 +80,8 @@ protected : bool factorize(Matrix& M, InvertData * invertData); void showInvalidSystemMessage(const std::string& reason) const; + + using Triplet = std::tuple; }; #if !defined(SOFA_COMPONENT_LINEARSOLVER_SPARSELDLSOLVER_CPP) diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl index 37b7b529e3d4..17ae6e1f0e0f 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl @@ -223,58 +223,75 @@ bool SparseLDLSolver::doAddJMInvJtLocal(ResMat } } - simulation::forEachRange(execution, *taskScheduler, 0u, JlocalRowSize, - [&data, this](const auto& range) - { - for (auto i = range.start; i != range.end; ++i) + { + SCOPED_TIMER("LowerSystem"); + simulation::forEachRange(execution, *taskScheduler, 0u, JlocalRowSize, + [&data, this](const auto& range) { - Real* line = JLinv[i]; - sofa::linearalgebra::solveLowerUnitriangularSystemCSR(data->n, line, line, data->LT_colptr.data(), data->LT_rowind.data(), data->LT_values.data()); - } - }); + SCOPED_TIMER("Lower"); + for (auto i = range.start; i != range.end; ++i) + { + Real* line = JLinv[i]; + sofa::linearalgebra::solveLowerUnitriangularSystemCSR(data->n, line, line, data->LT_colptr.data(), data->LT_rowind.data(), data->LT_values.data()); + } + }); + } - simulation::forEachRange(execution, *taskScheduler, 0u, JlocalRowSize, - [&data, this](const auto& range) - { - for (auto i = range.start; i != range.end; ++i) - { - Real* lineD = JLinv[i]; - Real* lineM = JLinvDinv[i]; - sofa::linearalgebra::solveDiagonalSystemUsingInvertedValues(data->n, lineD, lineM, data->invD.data()); - } - }); + { + SCOPED_TIMER("Diagonal"); + simulation::forEachRange(execution, *taskScheduler, 0u, JlocalRowSize, + [&data, this](const auto& range) + { + for (auto i = range.start; i != range.end; ++i) + { + Real* lineD = JLinv[i]; + Real* lineM = JLinvDinv[i]; + sofa::linearalgebra::solveDiagonalSystemUsingInvertedValues(data->n, lineD, lineM, data->invD.data()); + } + }); + } + const auto nbTriplets = JlocalRowSize * (JlocalRowSize+1) / 2; + std::vector tripletsBuffer(nbTriplets); + + SCOPED_TIMER("UpperSystem"); std::mutex mutex; - simulation::forEachRange(execution, *taskScheduler, 0u, JlocalRowSize, - [&data, this, fact, &mutex, result, JlocalRowSize](const auto& range) - { - std::vector > triplets; - triplets.reserve(JlocalRowSize * (range.end - range.start)); - for (auto j = range.start; j != range.end; ++j) + // Distribution of the tasks according to the number of triplets, i.e. the + // number of elements in a triangular matrix + simulation::forEachRange(execution, *taskScheduler, 0u, nbTriplets, + [&data, this, fact, &mutex, result, &tripletsBuffer](const auto& range) + { { - Real* lineJ = JLinvDinv[j]; - sofa::SignedIndex globalRowJ = Jlocal2global[j]; - for (unsigned i = j; i < JlocalRowSize; ++i) + SCOPED_TIMER("UpperRange"); + for (auto r = range.start; r != range.end; ++r) { + //convert a triangular matrix (flat) index to row and column coordinates + sofa::Index i, j; + linearalgebra::computeRowColumnCoordinateFromIndexInLowerTriangularMatrix(r, i, j); + + auto& [row, col, value] = tripletsBuffer[r]; + row = Jlocal2global[j]; + col = Jlocal2global[i]; + Real* lineI = JLinv[i]; - int globalRowI = Jlocal2global[i]; + Real* lineJ = JLinvDinv[j]; - Real acc = 0; - for (unsigned k = 0; k < (unsigned)data->n; k++) + value = 0; + for (int k = 0; k < data->n; ++k) { - acc += lineJ[k] * lineI[k]; + value += lineJ[k] * lineI[k]; } - acc *= fact; - - triplets.emplace_back(globalRowJ, globalRowI, acc); + value *= fact; } } std::lock_guard guard(mutex); - for (const auto& [row, col, value] : triplets) + SCOPED_TIMER("Assembling"); + for (auto r = range.start; r != range.end; ++r) { + const auto& [row, col, value] = tripletsBuffer[r]; result->add(row, col, value); if (row != col) { diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/TriangularSystemSolver.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/TriangularSystemSolver.h index 35b25f99bedc..e2f5fc63c53d 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/TriangularSystemSolver.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/TriangularSystemSolver.h @@ -22,6 +22,7 @@ #pragma once #include #include +#include namespace sofa::linearalgebra { @@ -96,4 +97,28 @@ void solveUpperUnitriangularSystemCSR( } } +/// A lower triangular matrix can be stored as a linear array. This function +/// converts the index in this linear array to 2d coordinates (row and column) +/// of an element in the matrix. +/// +/// Example of a 6x6 lower triangular matrix: +/// [ 0 ] +/// [ 1 2 ] +/// [ 3 4 5 ] +/// [ 6 7 8 9 ] +/// [10 11 12 13 14 ] +/// [15 16 17 18 19 20] +/// +/// 0 => (0, 0) +/// 7 => (3, 1) +/// 18 => (5, 3) +inline void computeRowColumnCoordinateFromIndexInLowerTriangularMatrix( + const sofa::Index flatIndex, + sofa::Index& row, + sofa::Index& col) +{ + row = std::floor(-0.5 + sqrt(0.25 + 2 * flatIndex)); + col = flatIndex - row * (row + 1) / 2; +} + } diff --git a/Sofa/framework/LinearAlgebra/test/TriangularSystemSolver_test.cpp b/Sofa/framework/LinearAlgebra/test/TriangularSystemSolver_test.cpp index 4e7215d851b4..c1230d807715 100644 --- a/Sofa/framework/LinearAlgebra/test/TriangularSystemSolver_test.cpp +++ b/Sofa/framework/LinearAlgebra/test/TriangularSystemSolver_test.cpp @@ -125,4 +125,27 @@ TEST(TriangularSystemSolver, upper3x3) EXPECT_FLOATINGPOINT_EQ(solution[0], static_cast(38)) } +TEST(TriangularSystemSolver, computeLowerTriangularMatrixCoordinates) +{ + for (sofa::Index matrixSize = 2; matrixSize < 50; ++matrixSize) + { + const auto nbElementsInATriangularMatrix = matrixSize * (matrixSize+1) / 2; + + sofa::Index nbCoordinates {}; + for (sofa::Index row = 0; row < matrixSize; ++row) + { + for (sofa::Index col = 0; col <= row; ++col) + { + sofa::Index r, c; + linearalgebra::computeRowColumnCoordinateFromIndexInLowerTriangularMatrix(nbCoordinates, r, c); + EXPECT_EQ(r, row) << "index " << nbCoordinates << ", matrix size " << matrixSize; + EXPECT_EQ(c, col) << "index " << nbCoordinates << ", matrix size " << matrixSize; + ++nbCoordinates; + } + } + + EXPECT_EQ(nbCoordinates, nbElementsInATriangularMatrix); + } +} + } diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/PipelineImpl.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/PipelineImpl.cpp index 1d201c1d16c5..f0cd613d37a7 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/PipelineImpl.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/PipelineImpl.cpp @@ -114,6 +114,7 @@ void PipelineImpl::computeCollisionDetection() { simulation::Node* root = dynamic_cast(getContext()); if(root == nullptr) return; + SCOPED_TIMER("CollisionDetection"); std::vector collisionModels; root->getTreeObjects(&collisionModels); doCollisionDetection(collisionModels); From 841d08bf99c6cfe431e9ac9a54bf2de53125b221 Mon Sep 17 00:00:00 2001 From: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Thu, 12 Oct 2023 13:59:35 +0200 Subject: [PATCH 15/60] [SofaCUDA] Move cuda GUI dependent code (#4227) * Move mouse interaction to a file activated only if qt is present. * removed headers * Added link to Sofa.GUI * Update applications/plugins/SofaCUDA/sofa/gpu/gui/CudaMouseInteraction.cpp Co-authored-by: erik pernod --------- Co-authored-by: erik pernod --- applications/plugins/SofaCUDA/CMakeLists.txt | 12 +++ .../plugins/SofaCUDA/FindCUDASparse.cmake | 2 +- .../SofaCUDA/sofa/gpu/cuda/CudaCollision.cpp | 49 +----------- .../sofa/gpu/gui/CudaMouseInteraction.cpp | 78 +++++++++++++++++++ 4 files changed, 92 insertions(+), 49 deletions(-) create mode 100644 applications/plugins/SofaCUDA/sofa/gpu/gui/CudaMouseInteraction.cpp diff --git a/applications/plugins/SofaCUDA/CMakeLists.txt b/applications/plugins/SofaCUDA/CMakeLists.txt index 2ea65239f9dd..18d32a9d0c54 100644 --- a/applications/plugins/SofaCUDA/CMakeLists.txt +++ b/applications/plugins/SofaCUDA/CMakeLists.txt @@ -330,12 +330,18 @@ else() message(STATUS "SofaCUDA: Plugin VolumetricRendering was not enabled/found, therefore CudaTetrahedralVisualModel will not be compiled.") endif() +sofa_find_package(Sofa.GUI QUIET) +if(Sofa.GUI_FOUND) + list(APPEND SOURCE_FILES sofa/gpu/gui/CudaMouseInteraction.cpp) +endif() + sofa_find_package(Sofa.GUI.Qt QUIET) if(Sofa.GUI.Qt_FOUND) list(APPEND HEADER_FILES sofa/gpu/gui/CudaDataWidget.h) list(APPEND SOURCE_FILES sofa/gpu/gui/CudaDataWidget.cpp) endif() + find_package(SofaDistanceGrid QUIET) if(SofaDistanceGrid_FOUND) sofa_find_package(MiniFlowVR QUIET) @@ -499,6 +505,12 @@ if(SofaDistanceGrid_FOUND) endif() endif() + +if(Sofa.GUI_FOUND) + target_link_libraries(${PROJECT_NAME} Sofa.GUI) +endif() + + if(Sofa.GUI.Qt_FOUND) target_link_libraries(${PROJECT_NAME} Sofa.GUI.Qt) endif() diff --git a/applications/plugins/SofaCUDA/FindCUDASparse.cmake b/applications/plugins/SofaCUDA/FindCUDASparse.cmake index a9ae0601dd91..a928e196610b 100644 --- a/applications/plugins/SofaCUDA/FindCUDASparse.cmake +++ b/applications/plugins/SofaCUDA/FindCUDASparse.cmake @@ -24,7 +24,7 @@ find_library(CUDA_SPARSE_LIBRARY NAMES cusparse PATHS "${CUDA_TOOLKIT_ROOT_DIR}" - PATH_SUFFIXES "/lib64" "/lib" "/lib/x86_64-linux-gnu" "lib/x64" "lib/Win32" + PATH_SUFFIXES "/lib64" "/lib" "/lib/x86_64-linux-gnu" "lib/x64" "lib/Win32" "/usr/local/cuda/lib64" DOC "Location of sparse library" NO_DEFAULT_PATH ) diff --git a/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaCollision.cpp b/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaCollision.cpp index 52720d900203..8558ccf86123 100644 --- a/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaCollision.cpp +++ b/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaCollision.cpp @@ -28,10 +28,7 @@ #include #include -#include -#include -#include -#include + #include #include @@ -51,42 +48,6 @@ #include #include -namespace sofa::gui::component::performer -{ - template class SOFA_GPU_CUDA_API MouseInteractor; - template class SOFA_GPU_CUDA_API TComponentMouseInteraction< CudaVec3fTypes >; - template class SOFA_GPU_CUDA_API AttachBodyPerformer< CudaVec3fTypes >; - template class SOFA_GPU_CUDA_API FixParticlePerformer< CudaVec3fTypes >; - -#ifdef SOFA_GPU_CUDA_DOUBLE - template class SOFA_GPU_CUDA_API MouseInteractor; - template class SOFA_GPU_CUDA_API TComponentMouseInteraction< CudaVec3dTypes >; - template class SOFA_GPU_CUDA_API AttachBodyPerformer< CudaVec3dTypes >; - template class SOFA_GPU_CUDA_API FixParticlePerformer< CudaVec3dTypes >; -#endif - -using namespace sofa::gpu::cuda; -using namespace sofa::component::collision; -using namespace sofa::component::collision::geometry; -using namespace sofa::component::collision::response::mapper; - -sofa::component::collision::response::mapper::ContactMapperCreator< sofa::component::collision::response::mapper::ContactMapper > CudaSphereContactMapperClass("PenalityContactForceField",true); - -helper::Creator > ComponentMouseInteractionCudaVec3fClass ("MouseSpringCudaVec3f",true); -helper::Creator > AttachBodyPerformerCudaVec3fClass("AttachBody",true); -helper::Creator > FixParticlePerformerCudaVec3fClass("FixParticle",true); - -#ifdef SOFA_GPU_CUDA_DOUBLE -helper::Creator > ComponentMouseInteractionCudaVec3dClass ("MouseSpringCudaVec3d",true); -helper::Creator > AttachBodyPerformerCudaVec3dClass("AttachBody",true); -helper::Creator > FixParticlePerformerCudaVec3dClass("FixParticle",true); -#endif - -using FixParticlePerformerCuda3d = FixParticlePerformer; - -int triangleFixParticle = FixParticlePerformerCuda3d::RegisterSupportedModel>(&FixParticlePerformerCuda3d::getFixationPointsTriangle>); - -} // namespace sofa::gui::component::performer @@ -97,15 +58,7 @@ using namespace sofa::component::collision; using namespace sofa::component::collision::geometry; using namespace sofa::component::collision::detection::intersection; using namespace sofa::component::collision::response::contact; -using namespace sofa::gui::component::performer; - -int MouseInteractorCudaClass = core::RegisterObject("Supports Mouse Interaction using CUDA") - .add< MouseInteractor >() -#ifdef SOFA_GPU_CUDA_DOUBLE - .add< MouseInteractor >() -#endif - ; class CudaProximityIntersection : public NewProximityIntersection { diff --git a/applications/plugins/SofaCUDA/sofa/gpu/gui/CudaMouseInteraction.cpp b/applications/plugins/SofaCUDA/sofa/gpu/gui/CudaMouseInteraction.cpp new file mode 100644 index 000000000000..ecda062c6389 --- /dev/null +++ b/applications/plugins/SofaCUDA/sofa/gpu/gui/CudaMouseInteraction.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +namespace sofa::gui::component::performer +{ +template class SOFA_GPU_CUDA_API MouseInteractor; +template class SOFA_GPU_CUDA_API TComponentMouseInteraction< CudaVec3fTypes >; +template class SOFA_GPU_CUDA_API AttachBodyPerformer< CudaVec3fTypes >; +template class SOFA_GPU_CUDA_API FixParticlePerformer< CudaVec3fTypes >; + +#ifdef SOFA_GPU_CUDA_DOUBLE +template class SOFA_GPU_CUDA_API MouseInteractor; +template class SOFA_GPU_CUDA_API TComponentMouseInteraction< CudaVec3dTypes >; +template class SOFA_GPU_CUDA_API AttachBodyPerformer< CudaVec3dTypes >; +template class SOFA_GPU_CUDA_API FixParticlePerformer< CudaVec3dTypes >; +#endif + +using namespace sofa::gpu::cuda; +using namespace sofa::component::collision; +using namespace sofa::component::collision::geometry; +using namespace sofa::component::collision::response::mapper; + +sofa::component::collision::response::mapper::ContactMapperCreator< sofa::component::collision::response::mapper::ContactMapper > CudaSphereContactMapperClass("PenalityContactForceField",true); + +helper::Creator > ComponentMouseInteractionCudaVec3fClass ("MouseSpringCudaVec3f",true); +helper::Creator > AttachBodyPerformerCudaVec3fClass("AttachBody",true); +helper::Creator > FixParticlePerformerCudaVec3fClass("FixParticle",true); + +#ifdef SOFA_GPU_CUDA_DOUBLE +helper::Creator > ComponentMouseInteractionCudaVec3dClass ("MouseSpringCudaVec3d",true); +helper::Creator > AttachBodyPerformerCudaVec3dClass("AttachBody",true); +helper::Creator > FixParticlePerformerCudaVec3dClass("FixParticle",true); +#endif + +using FixParticlePerformerCuda3d = FixParticlePerformer; + +int triangleFixParticle = FixParticlePerformerCuda3d::RegisterSupportedModel>(&FixParticlePerformerCuda3d::getFixationPointsTriangle>); + +} // namespace sofa::gui::component::performer + + + +namespace sofa::gpu::cuda +{ + +using namespace sofa::gui::component::performer; + +int MouseInteractorCudaClass = core::RegisterObject("Supports Mouse Interaction using CUDA") + .add< MouseInteractor >() +#ifdef SOFA_GPU_CUDA_DOUBLE + .add< MouseInteractor >() +#endif + ; + +} From 5433100ae4287c282b68b5360d5a8557143fe362 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Mon, 16 Oct 2023 17:13:49 +0200 Subject: [PATCH 16/60] [Helper] Update ComponentChange for MechanicalMatrixMapper (#4235) and MappingGeometricStiffnessForceField The message goes from: ``` Object type MechanicalMatrixMapper was not created The object 'MechanicalMatrixMapper' is not in the factory. This component has been MOVED from SofaGeneralAnimationLoop to Sofa.Component.Mapping.MappedMatrix since SOFA v22.06. To continue using this component you may need to update your scene by adding ``` to: ``` The object 'MechanicalMatrixMapper' is not in the factory. This component has been REMOVED since SOFA v23.06 (deprecated since v23.12). Please consider updating your scene. If this component is crucial to you please report in a GitHub issue in order to reconsider this component for future re-integration. ``` --- Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp b/Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp index 8f496f1bae1f..b7958a4da16f 100644 --- a/Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp +++ b/Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp @@ -470,7 +470,6 @@ const std::map > uncreatableComponents { "VoidMapping", Moved("v22.06", "SofaMiscMapping", "Sofa.Component.Mapping.Linear") }, // SofaConstraint was deprecated in #2635, #2790, #2796, #2813 and ... - { "MappingGeometricStiffnessForceField", Moved("v22.06", "SofaConstraint", "Sofa.Component.Mapping.MappedMatrix") }, { "BilateralInteractionConstraint", Moved("v22.06", "SofaConstraint", "Sofa.Component.Constraint.Lagrangian.Model") }, { "GenericConstraintCorrection", Moved("v22.06", "SofaConstraint", "Sofa.Component.Constraint.Lagrangian.Correction") }, { "GenericConstraintSolver", Moved("v22.06", "SofaConstraint", "Sofa.Component.Constraint.Lagrangian.Solver") }, @@ -487,7 +486,6 @@ const std::map > uncreatableComponents { "LocalMinDistance", Moved("v22.06", "SofaConstraint", "Sofa.Component.Collision.Detection.Intersection") }, // SofaGeneralAnimationLoop was deprecated in #2635 and #2796 - { "MechanicalMatrixMapper", Moved("v22.06", "SofaGeneralAnimationLoop", "Sofa.Component.Mapping.MappedMatrix") }, { "MultiStepAnimationLoop", Moved("v22.06", "SofaGeneralAnimationLoop", "Sofa.Component.AnimationLoop") }, { "MultiTagAnimationLoop", Moved("v22.06", "SofaGeneralAnimationLoop", "Sofa.Component.AnimationLoop") }, @@ -718,6 +716,10 @@ const std::map > uncreatableComponents // SofaValidation was deprecated in #3039 { "CompareState", Moved("v22.06", "SofaValidation", "Sofa.Component.Playback") }, { "CompareTopology", Moved("v22.06", "SofaValidation", "Sofa.Component.Playback") }, + + // Removed in #4040, deprecated in #2777 + { "MechanicalMatrixMapper", Removed("v23.06", "v23.12") }, + { "MappingGeometricStiffnessForceField", Removed("v23.06", "v23.12") }, }; } // namespace sofa::helper::lifecycle From a8c09185bd6980823691e6c5ea2db9b784ed8ea2 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Tue, 17 Oct 2023 04:42:00 +0200 Subject: [PATCH 17/60] [all] Forgotten scoped timers (#4237) Co-authored-by: Frederick Roy --- .../animationloop/FreeMotionAnimationLoop.cpp | 24 +++++++++---------- .../detection/algorithm/CollisionPipeline.cpp | 10 ++++---- .../odesolver/backward/StaticSolver.cpp | 14 +++++------ .../algorithm/ParallelBVHNarrowPhase.cpp | 8 +++---- .../ParallelBruteForceBroadPhase.cpp | 6 ++--- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp b/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp index d701c75a4c66..ef7bfdc46097 100644 --- a/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp +++ b/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp @@ -182,7 +182,7 @@ void FreeMotionAnimationLoop::step(const sofa::core::ExecParams* params, SReal d // This solver will work in freePosition and freeVelocity vectors. // We need to initialize them if it's not already done. { - ScopedAdvancedTimer timer("MechanicalVInitVisitor"); + SCOPED_TIMER("MechanicalVInitVisitor"); MechanicalVInitVisitor< core::V_COORD >(params, core::VecCoordId::freePosition(), core::ConstVecCoordId::position(), true).execute(node); MechanicalVInitVisitor< core::V_DERIV >(params, core::VecDerivId::freeVelocity(), core::ConstVecDerivId::velocity(), true).execute(node); } @@ -201,7 +201,7 @@ void FreeMotionAnimationLoop::step(const sofa::core::ExecParams* params, SReal d #endif { - ScopedAdvancedTimer timer("AnimateBeginEvent"); + SCOPED_TIMER("AnimateBeginEvent"); AnimateBeginEvent ev ( dt ); PropagateEventVisitor act ( params, &ev ); node->execute ( act ); @@ -212,7 +212,7 @@ void FreeMotionAnimationLoop::step(const sofa::core::ExecParams* params, SReal d dmsg_info() << "updatePos called" ; { - ScopedAdvancedTimer timer("UpdatePosition"); + SCOPED_TIMER("UpdatePosition"); BehaviorUpdatePositionVisitor beh(params, dt); node->execute(&beh); } @@ -224,7 +224,7 @@ void FreeMotionAnimationLoop::step(const sofa::core::ExecParams* params, SReal d dmsg_info() << "updateInternal called" ; { - ScopedAdvancedTimer timer("updateInternalData"); + SCOPED_TIMER("updateInternalData"); node->execute(&iud); } @@ -239,14 +239,14 @@ void FreeMotionAnimationLoop::step(const sofa::core::ExecParams* params, SReal d // Mapping geometric stiffness coming from previous lambda. { - ScopedAdvancedTimer timer("lambdaMultInvDt"); + SCOPED_TIMER("lambdaMultInvDt"); MechanicalVOpVisitor lambdaMultInvDt(params, cparams.lambda(), sofa::core::ConstMultiVecId::null(), cparams.lambda(), 1.0 / dt); lambdaMultInvDt.setMapped(true); node->executeVisitor(&lambdaMultInvDt); } { - ScopedAdvancedTimer timer("MechanicalComputeGeometricStiffness"); + SCOPED_TIMER("MechanicalComputeGeometricStiffness"); MechanicalComputeGeometricStiffness geometricStiffnessVisitor(&mop.mparams, cparams.lambda()); node->executeVisitor(&geometricStiffnessVisitor); } @@ -256,7 +256,7 @@ void FreeMotionAnimationLoop::step(const sofa::core::ExecParams* params, SReal d // Solve constraints if (l_constraintSolver) { - ScopedAdvancedTimer timer("ConstraintSolver"); + SCOPED_TIMER("ConstraintSolver"); if (cparams.constOrder() == core::ConstraintParams::VEL ) { @@ -283,14 +283,14 @@ void FreeMotionAnimationLoop::step(const sofa::core::ExecParams* params, SReal d node->execute(params); // propagate time { - ScopedAdvancedTimer timer("AnimateEndEvent"); + SCOPED_TIMER("AnimateEndEvent"); AnimateEndEvent ev ( dt ); PropagateEventVisitor act ( params, &ev ); node->execute ( act ); } { - ScopedAdvancedTimer timer("UpdateMapping"); + SCOPED_TIMER("UpdateMapping"); //Visual Information update: Ray Pick add a MechanicalMapping used as VisualMapping node->execute(params); { @@ -302,7 +302,7 @@ void FreeMotionAnimationLoop::step(const sofa::core::ExecParams* params, SReal d if (d_computeBoundingBox.getValue()) { - ScopedAdvancedTimer timer("UpdateBBox"); + SCOPED_TIMER("UpdateBBox"); node->execute(params); } @@ -323,7 +323,7 @@ void FreeMotionAnimationLoop::computeFreeMotionAndCollisionDetection(const sofa: if (!d_parallelCollisionDetectionAndFreeMotion.getValue()) { - ScopedAdvancedTimer timer("FreeMotion+CollisionDetection"); + SCOPED_TIMER("FreeMotion+CollisionDetection"); computeFreeMotion(params, cparams, dt, pos, freePos, freeVel, mop); @@ -334,7 +334,7 @@ void FreeMotionAnimationLoop::computeFreeMotionAndCollisionDetection(const sofa: } else { - ScopedAdvancedTimer timer("FreeMotion+CollisionDetection"); + SCOPED_TIMER("FreeMotion+CollisionDetection"); auto* taskScheduler = sofa::simulation::MainTaskSchedulerFactory::createInRegistry(); assert(taskScheduler != nullptr); diff --git a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/CollisionPipeline.cpp b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/CollisionPipeline.cpp index 66118e003017..24209c2362df 100644 --- a/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/CollisionPipeline.cpp +++ b/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/CollisionPipeline.cpp @@ -132,7 +132,7 @@ void CollisionPipeline::doCollisionReset() void CollisionPipeline::doCollisionDetection(const type::vector& collisionModels) { - ScopedAdvancedTimer docollisiontimer("doCollisionDetection"); + SCOPED_TIMER_VARNAME(docollisiontimer, "doCollisionDetection"); msg_info_when(d_doPrintInfoMessage.getValue()) << "doCollisionDetection, compute Bounding Trees" ; @@ -142,7 +142,7 @@ void CollisionPipeline::doCollisionDetection(const type::vector vectBoundingVolume; { - ScopedAdvancedTimer bboxtimer("ComputeBoundingTree"); + SCOPED_TIMER_VARNAME(bboxtimer, "ComputeBoundingTree"); #ifdef SOFA_DUMP_VISITOR_INFO simulation::Visitor::printNode("ComputeBoundingTree"); @@ -203,7 +203,7 @@ void CollisionPipeline::doCollisionDetection(const type::vectorbeginBroadPhase(); broadPhaseDetection->beginBroadPhase(); broadPhaseDetection->addCollisionModels(vectBoundingVolume); // detection is done there @@ -227,7 +227,7 @@ void CollisionPipeline::doCollisionDetection(const type::vectorbeginNarrowPhase(); narrowPhaseDetection->beginNarrowPhase(); const type::vector >& vectCMPair = broadPhaseDetection->getCollisionModelPairs(); @@ -291,7 +291,7 @@ void CollisionPipeline::doCollisionResponse() if (groupManager == nullptr) { - ScopedAdvancedTimer createResponseTimer("CreateMovingObjectsResponse"); + SCOPED_TIMER_VARNAME(createResponseTimer, "CreateMovingObjectsResponse"); msg_info_when(d_doPrintInfoMessage.getValue()) << "Linking all contacts to Scene" ; diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp index f58dc8349417..d3d8413877c3 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp @@ -155,7 +155,7 @@ void StaticSolver::solve(const sofa::core::ExecParams* params, SReal dt, sofa::c } // Start the advanced timer - ScopedAdvancedTimer timer ("StaticSolver::Solve"); + SCOPED_TIMER("StaticSolver::Solve"); // ########################################################################### // # First residual # @@ -202,13 +202,13 @@ void StaticSolver::solve(const sofa::core::ExecParams* params, SReal dt, sofa::c while (! converged && n_it < max_number_of_newton_iterations) { - ScopedAdvancedTimer step_timer ("NewtonStep"); + SCOPED_TIMER_VARNAME(step_timer, "NewtonStep"); t = steady_clock::now(); // Part I. Assemble the system matrix. MultiMatrix matrix(&mop); { - ScopedAdvancedTimer _t_("MBKBuild"); + SCOPED_TIMER("MBKBuild"); // 1. The MechanicalMatrix::K is a simple structure that stores three floats called factors: m, b and k. // 2. the * operator simply multiplies each of the three factors with a value. No matrix is built yet. // 3. The = operator first search for a linear solver in the current context. It then calls the @@ -225,7 +225,7 @@ void StaticSolver::solve(const sofa::core::ExecParams* params, SReal dt, sofa::c // Part II. Solve the unknown increment. { - ScopedAdvancedTimer _t_("MBKSolve"); + SCOPED_TIMER("MBKSolve"); // Calls methods "setSystemRHVector", "setSystemLHVector" and "solveSystem" of the LinearSolver component // for CG: calls iteratively addDForce, mapped: [applyJ, addDForce, applyJt(vec)]+ // for Direct: solves the system, everything's already assembled @@ -234,7 +234,7 @@ void StaticSolver::solve(const sofa::core::ExecParams* params, SReal dt, sofa::c // Part III. Propagate the solution increment and update geometry. { - ScopedAdvancedTimer _t_("PropagateDx"); + SCOPED_TIMER("PropagateDx"); // Updating the geometry x.peq(dx); // x := x + dx @@ -263,7 +263,7 @@ void StaticSolver::solve(const sofa::core::ExecParams* params, SReal dt, sofa::c // Part IV. Update the force vector. { - ScopedAdvancedTimer _t_("UpdateForce"); + SCOPED_TIMER("UpdateForce"); mop.computeForce(force); mop.projectResponse(force); @@ -271,7 +271,7 @@ void StaticSolver::solve(const sofa::core::ExecParams* params, SReal dt, sofa::c // Part V. Compute the updated norms. { - ScopedAdvancedTimer _t_("ComputeNorms"); + SCOPED_TIMER("ComputeNorms"); // Residual norm R_squared_norm = force.dot(force); diff --git a/applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBVHNarrowPhase.cpp b/applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBVHNarrowPhase.cpp index abcd6ed1ab9c..3cf5782a58d7 100644 --- a/applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBVHNarrowPhase.cpp +++ b/applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBVHNarrowPhase.cpp @@ -56,7 +56,7 @@ void ParallelBVHNarrowPhase::init() void ParallelBVHNarrowPhase::addCollisionPairs(const sofa::type::vector< std::pair >& v) { - ScopedAdvancedTimer addCollisionPairsTimer("addCollisionPairs"); + SCOPED_TIMER_VARNAME(addCollisionPairsTimer, "addCollisionPairs"); if (v.empty()) { @@ -71,7 +71,7 @@ void ParallelBVHNarrowPhase::addCollisionPairs(const sofa::type::vector< std::pa m_tasks.reserve(nbPairs); { - ScopedAdvancedTimer createTasksTimer("TasksCreation"); + SCOPED_TIMER_VARNAME(createTasksTimer, "TasksCreation"); for (const auto &pair : v) { m_tasks.emplace_back(&status, this, pair); @@ -80,7 +80,7 @@ void ParallelBVHNarrowPhase::addCollisionPairs(const sofa::type::vector< std::pa } { - ScopedAdvancedTimer waitTimer("ParallelTasks"); + SCOPED_TIMER_VARNAME(waitTimer, "ParallelTasks"); m_taskScheduler->workUntilDone(&status); } @@ -93,7 +93,7 @@ void ParallelBVHNarrowPhase::addCollisionPairs(const sofa::type::vector< std::pa void ParallelBVHNarrowPhase::createOutput( const sofa::type::vector> &v) { - ScopedAdvancedTimer createTasksTimer("OutputCreation"); + SCOPED_TIMER_VARNAME(createTasksTimer, "OutputCreation"); for (const auto &pair : v) { diff --git a/applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBruteForceBroadPhase.cpp b/applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBruteForceBroadPhase.cpp index cb796d445d4e..2650868a9138 100644 --- a/applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBruteForceBroadPhase.cpp +++ b/applications/plugins/MultiThreading/src/MultiThreading/component/collision/detection/algorithm/ParallelBruteForceBroadPhase.cpp @@ -81,7 +81,7 @@ void ParallelBruteForceBroadPhase::addCollisionModel(sofa::core::CollisionModel void ParallelBruteForceBroadPhase::addCollisionModels(const sofa::type::vector& v) { - ScopedAdvancedTimer timer("ParallelBruteForceBroadPhase::addCollisionModels"); + SCOPED_TIMER("ParallelBruteForceBroadPhase::addCollisionModels"); m_pairs.clear(); BroadPhaseDetection::addCollisionModels(v); @@ -94,7 +94,7 @@ void ParallelBruteForceBroadPhase::addCollisionModels(const sofa::type::vector(m_pairs.size()); @@ -123,7 +123,7 @@ void ParallelBruteForceBroadPhase::addCollisionModels(const sofa::type::vectorworkUntilDone(&status); } From f6bee9f9cd69ebd102324e0181325329f96ada94 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Tue, 17 Oct 2023 09:03:50 +0200 Subject: [PATCH 18/60] [Constraint.Lagrangian.Solver] Another step to factorize both constraint solvers (#4213) * Change ConstOrder for an enum class * Remove overcomplicated macro * Simplify solveConstraint * API is marked deprecated but still used for more than a decade * Minor cleaning * Remove isActive lists * minor changes * Factorize build_LCP and build_problem_info * Minor changes * Factorize resetConstraints * Factorize buildConstraintMatrix * Factorize accumulateMatrixDeriv * Move buildSystem close to its call * Continue factorization * Fix velocity input * Minor factorization * add documentation * Rename ConstOrder to ConstraintOrder The enum is also moved in its dedicated file --- .../animationloop/FreeMotionAnimationLoop.cpp | 8 +- .../GenericConstraintCorrection.cpp | 8 +- .../LinearSolverConstraintCorrection.inl | 12 +- .../PrecomputedConstraintCorrection.inl | 8 +- .../UncoupledConstraintCorrection.inl | 8 +- .../model/BilateralInteractionConstraint.inl | 2 +- .../lagrangian/model/UniformConstraint.inl | 2 +- .../model/UnilateralInteractionConstraint.inl | 8 +- .../solver/ConstraintSolverImpl.cpp | 49 ++++ .../lagrangian/solver/ConstraintSolverImpl.h | 20 ++ .../solver/GenericConstraintSolver.cpp | 250 ++++++++---------- .../solver/GenericConstraintSolver.h | 25 +- .../lagrangian/solver/LCPConstraintSolver.cpp | 219 ++++----------- .../lagrangian/solver/LCPConstraintSolver.h | 15 +- .../backward/EulerImplicitSolver.cpp | 12 +- .../backward/NewmarkImplicitSolver.cpp | 8 +- .../odesolver/backward/StaticSolver.cpp | 2 +- .../backward/VariationalSymplecticSolver.cpp | 8 +- .../forward/CentralDifferenceSolver.cpp | 14 +- .../odesolver/forward/EulerSolver.cpp | 14 +- .../odesolver/forward/RungeKutta2Solver.cpp | 8 +- .../odesolver/forward/RungeKutta4Solver.cpp | 8 +- .../statecontainer/MechanicalObject.inl | 2 + Sofa/framework/Core/CMakeLists.txt | 1 + .../Core/src/sofa/core/ConstraintOrder.h | 57 ++++ .../Core/src/sofa/core/ConstraintParams.cpp | 2 +- .../Core/src/sofa/core/ConstraintParams.h | 51 ++-- .../core/behavior/BaseConstraintCorrection.h | 3 - .../sofa/core/behavior/ConstraintSolver.cpp | 63 ++--- .../src/sofa/core/behavior/ConstraintSolver.h | 6 + Sofa/framework/Core/src/sofa/core/config.h.in | 7 + .../Helper/src/sofa/helper/LCPcalc.cpp | 36 +-- .../Helper/src/sofa/helper/OptionsGroup.h | 1 - .../src/sofa/helper/ScopedAdvancedTimer.h | 2 +- .../sofa/simulation/MechanicalOperations.cpp | 6 +- .../sofa/simulation/MechanicalOperations.h | 2 +- .../MechanicalIntegrateConstraintVisitor.cpp | 2 +- 37 files changed, 467 insertions(+), 482 deletions(-) create mode 100644 Sofa/framework/Core/src/sofa/core/ConstraintOrder.h diff --git a/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp b/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp index ef7bfdc46097..645ca99947f9 100644 --- a/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp +++ b/Sofa/Component/AnimationLoop/src/sofa/component/animationloop/FreeMotionAnimationLoop.cpp @@ -171,7 +171,7 @@ void FreeMotionAnimationLoop::step(const sofa::core::ExecParams* params, SReal d cparams.setV(freeVel); cparams.setDx(l_constraintSolver->getDx()); cparams.setLambda(l_constraintSolver->getLambda()); - cparams.setOrder(m_solveVelocityConstraintFirst.getValue() ? core::ConstraintParams::VEL : core::ConstraintParams::POS_AND_VEL); + cparams.setOrder(m_solveVelocityConstraintFirst.getValue() ? core::ConstraintOrder::VEL : core::ConstraintOrder::POS_AND_VEL); MultiVecDeriv dx(&vop, core::VecDerivId::dx()); dx.realloc(&vop, !d_threadSafeVisitor.getValue(), true); @@ -258,7 +258,7 @@ void FreeMotionAnimationLoop::step(const sofa::core::ExecParams* params, SReal d { SCOPED_TIMER("ConstraintSolver"); - if (cparams.constOrder() == core::ConstraintParams::VEL ) + if (cparams.constOrder() == core::ConstraintOrder::VEL ) { l_constraintSolver->solveConstraint(&cparams, vel); pos.eq(pos, vel, dt); //position += velocity * dt @@ -391,8 +391,8 @@ void FreeMotionAnimationLoop::computeFreeMotion(const sofa::core::ExecParams* pa mop->projectResponse(freeVel); mop->propagateDx(freeVel, true); - if (cparams.constOrder() == sofa::core::ConstraintParams::POS || - cparams.constOrder() == sofa::core::ConstraintParams::POS_AND_VEL) + if (cparams.constOrder() == sofa::core::ConstraintOrder::POS || + cparams.constOrder() == sofa::core::ConstraintOrder::POS_AND_VEL) { SCOPED_TIMER("freePosEqPosPlusFreeVelDt"); MechanicalVOpVisitor freePosEqPosPlusFreeVelDt(params, freePos, pos, freeVel, dt); diff --git a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/GenericConstraintCorrection.cpp b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/GenericConstraintCorrection.cpp index af97de230433..30a0efcfdcd6 100644 --- a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/GenericConstraintCorrection.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/GenericConstraintCorrection.cpp @@ -151,13 +151,13 @@ void GenericConstraintCorrection::addComplianceInConstraintSpace(const Constrain switch (cparams->constOrder()) { - case ConstraintParams::POS_AND_VEL : - case ConstraintParams::POS : + case sofa::core::ConstraintOrder::POS_AND_VEL : + case sofa::core::ConstraintOrder::POS : factor = l_ODESolver.get()->getPositionIntegrationFactor(); break; - case ConstraintParams::ACC : - case ConstraintParams::VEL : + case sofa::core::ConstraintOrder::ACC : + case sofa::core::ConstraintOrder::VEL : factor = l_ODESolver.get()->getVelocityIntegrationFactor(); break; diff --git a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/LinearSolverConstraintCorrection.inl b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/LinearSolverConstraintCorrection.inl index a33fbbfbd8b8..2e228d321a82 100644 --- a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/LinearSolverConstraintCorrection.inl +++ b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/LinearSolverConstraintCorrection.inl @@ -174,14 +174,14 @@ void LinearSolverConstraintCorrection::addComplianceInConstraintSpace switch (cparams->constOrder()) { - case core::ConstraintParams::POS_AND_VEL : - case core::ConstraintParams::POS : - factor = l_ODESolver.get()->getPositionIntegrationFactor(); + case core::ConstraintOrder::POS_AND_VEL : + case core::ConstraintOrder::POS : + factor = l_ODESolver->getPositionIntegrationFactor(); break; - case core::ConstraintParams::ACC : - case core::ConstraintParams::VEL : - factor = l_ODESolver.get()->getVelocityIntegrationFactor(); + case core::ConstraintOrder::ACC : + case core::ConstraintOrder::VEL : + factor = l_ODESolver->getVelocityIntegrationFactor(); break; default : diff --git a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/PrecomputedConstraintCorrection.inl b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/PrecomputedConstraintCorrection.inl index cf700aa980af..10f6d0f6b538 100644 --- a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/PrecomputedConstraintCorrection.inl +++ b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/PrecomputedConstraintCorrection.inl @@ -420,12 +420,12 @@ void PrecomputedConstraintCorrection< DataTypes >::addComplianceInConstraintSpac switch (cparams->constOrder()) { - case core::ConstraintParams::POS_AND_VEL : - case core::ConstraintParams::POS : + case core::ConstraintOrder::POS_AND_VEL : + case core::ConstraintOrder::POS : break; - case core::ConstraintParams::ACC : - case core::ConstraintParams::VEL : + case core::ConstraintOrder::ACC : + case core::ConstraintOrder::VEL : factor = 1.0 / this->getContext()->getDt(); // @TODO : Consistency between ODESolver & Compliance and/or Admittance computation break; diff --git a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.inl b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.inl index 2a073c7a379d..ef53af25c24c 100644 --- a/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.inl +++ b/Sofa/Component/Constraint/Lagrangian/Correction/src/sofa/component/constraint/lagrangian/correction/UncoupledConstraintCorrection.inl @@ -295,13 +295,13 @@ void UncoupledConstraintCorrection::addComplianceInConstraintSpace(co SReal factor = 1.0; switch (cparams->constOrder()) { - case core::ConstraintParams::POS_AND_VEL : - case core::ConstraintParams::POS : + case core::ConstraintOrder::POS_AND_VEL : + case core::ConstraintOrder::POS : factor = useOdeIntegrationFactors ? m_pOdeSolver->getPositionIntegrationFactor() : 1.0; break; - case core::ConstraintParams::ACC : - case core::ConstraintParams::VEL : + case core::ConstraintOrder::ACC : + case core::ConstraintOrder::VEL : factor = useOdeIntegrationFactors ? m_pOdeSolver->getVelocityIntegrationFactor() : 1.0; break; diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.inl index c1be870f9f59..0aeec985ed2d 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.inl +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BilateralInteractionConstraint.inl @@ -182,7 +182,7 @@ void BilateralInteractionConstraint::getConstraintViolation(const Con const VecDeriv& restVector = this->restVector.getValue(); - if (cParams->constOrder() == ConstraintParams::VEL) + if (cParams->constOrder() == sofa::core::ConstraintOrder::VEL) { getVelocityViolation(v, d_x1, d_x2, d_v1, d_v2); return; diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.inl index ca5a28cfe85a..b34a9377b97a 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.inl +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UniformConstraint.inl @@ -88,7 +88,7 @@ void UniformConstraint::getConstraintViolation(const sofa::core::Cons auto pos = this->getMState()->readPositions(); auto restPos = this->getMState()->readRestPositions(); - if (cParams->constOrder() == sofa::core::ConstraintParams::VEL) + if (cParams->constOrder() == sofa::core::ConstraintOrder::VEL) { if (d_constraintRestPos.getValue()){ computeViolation(resV, m_constraintIndex, vfree, Deriv::size(),[&invDt,&pos,&vfree,&restPos](int i, int j) diff --git a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.inl b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.inl index aaa8c0a2b498..7cd50ba7b9b5 100644 --- a/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.inl +++ b/Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/UnilateralInteractionConstraint.inl @@ -295,13 +295,13 @@ void UnilateralInteractionConstraint::getConstraintViolation(const co { switch (cparams->constOrder()) { - case core::ConstraintParams::POS_AND_VEL : - case core::ConstraintParams::POS : + case core::ConstraintOrder::POS_AND_VEL : + case core::ConstraintOrder::POS : getPositionViolation(v); break; - case core::ConstraintParams::ACC : - case core::ConstraintParams::VEL : + case core::ConstraintOrder::ACC : + case core::ConstraintOrder::VEL : getVelocityViolation(v); break; diff --git a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/ConstraintSolverImpl.cpp b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/ConstraintSolverImpl.cpp index 58893a90b8ca..e472cdba283b 100644 --- a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/ConstraintSolverImpl.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/ConstraintSolverImpl.cpp @@ -21,9 +21,15 @@ ******************************************************************************/ #include +#include #include #include #include +#include +#include +#include +#include + namespace sofa::component::constraint::lagrangian::solver { @@ -112,5 +118,48 @@ void ConstraintSolverImpl::clearConstraintCorrections() l_constraintCorrections.clear(); } +void ConstraintSolverImpl::resetConstraints(const core::ConstraintParams* cParams) +{ + SCOPED_TIMER("Reset Constraint"); + simulation::mechanicalvisitor::MechanicalResetConstraintVisitor(cParams).execute(getContext()); +} + +void ConstraintSolverImpl::buildLocalConstraintMatrix(const core::ConstraintParams* cparams, unsigned int &constraintId) +{ + SCOPED_TIMER("Build Local Constraint Matrix"); + simulation::mechanicalvisitor::MechanicalBuildConstraintMatrix buildConstraintMatrix(cparams, cparams->j(), constraintId ); + buildConstraintMatrix.execute(getContext()); +} + +void ConstraintSolverImpl::accumulateMatrixDeriv(const core::ConstraintParams* cparams) +{ + SCOPED_TIMER("Project Mapped Constraint Matrix"); + simulation::mechanicalvisitor::MechanicalAccumulateMatrixDeriv accumulateMatrixDeriv(cparams, cparams->j()); + accumulateMatrixDeriv.execute(getContext()); +} + +unsigned int ConstraintSolverImpl::buildConstraintMatrix(const core::ConstraintParams* cparams) +{ + SCOPED_TIMER("Build Constraint Matrix"); + unsigned int constraintId {}; + resetConstraints(cparams); + buildLocalConstraintMatrix(cparams, constraintId); + accumulateMatrixDeriv(cparams); + return constraintId; +} + +void ConstraintSolverImpl::applyProjectiveConstraintOnConstraintMatrix(const core::ConstraintParams* cparams) +{ + core::MechanicalParams mparams = core::MechanicalParams(*cparams); + simulation::mechanicalvisitor::MechanicalProjectJacobianMatrixVisitor(&mparams).execute(getContext()); +} + +void ConstraintSolverImpl::getConstraintViolation( + const core::ConstraintParams* cparams, sofa::linearalgebra::BaseVector* v) +{ + SCOPED_TIMER("Get Constraint Value"); + MechanicalGetConstraintViolationVisitor(cparams, v).execute(getContext()); +} + } //namespace sofa::component::constraint::lagrangian::solver diff --git a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/ConstraintSolverImpl.h b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/ConstraintSolverImpl.h index b049c4e51334..82aee17d67b4 100644 --- a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/ConstraintSolverImpl.h +++ b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/ConstraintSolverImpl.h @@ -93,6 +93,26 @@ class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API ConstraintSolverImpl : pub core::behavior::BaseConstraintCorrection, BaseLink::FLAG_STOREPATH> l_constraintCorrections; + /// Calls the method resetConstraint on all the mechanical states and BaseConstraintSet + /// In the case of a MechanicalObject, it clears the constraint jacobian matrix + void resetConstraints(const core::ConstraintParams* cParams); + + /// Call the method buildConstraintMatrix on all the BaseConstraintSet + void buildLocalConstraintMatrix(const core::ConstraintParams* cparams, unsigned int &constraintId); + + /// Calls the method applyJT on all the mappings to project the mapped + /// constraint matrices on the main constraint matrix + void accumulateMatrixDeriv(const core::ConstraintParams* cparams); + + /// Reset and build the constraint matrix, including the projection from + /// the mapped DoFs + /// \return The number of constraints, i.e. the size of the constraint matrix + unsigned int buildConstraintMatrix(const core::ConstraintParams* cparams); + + void applyProjectiveConstraintOnConstraintMatrix(const core::ConstraintParams* cparams); + + void getConstraintViolation(const core::ConstraintParams* cparams, sofa::linearalgebra::BaseVector *v); + }; } //namespace sofa::component::constraint::lagrangian::solver diff --git a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.cpp b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.cpp index 3d317311b6ee..16d1e17e8329 100644 --- a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.cpp @@ -37,15 +37,6 @@ #include using sofa::simulation::mechanicalvisitor::MechanicalVOpVisitor; -#include -using sofa::simulation::mechanicalvisitor::MechanicalResetConstraintVisitor; - -#include -using sofa::simulation::mechanicalvisitor::MechanicalBuildConstraintMatrix; - -#include -using sofa::simulation::mechanicalvisitor::MechanicalAccumulateMatrixDeriv; - #include using sofa::simulation::mechanicalvisitor::MechanicalProjectJacobianMatrixVisitor; @@ -57,6 +48,7 @@ namespace using sofa::helper::WriteOnlyAccessor; using sofa::core::objectmodel::Data; +using sofa::core::ConstraintParams; template< typename TMultiVecId > void clearMultiVecId(sofa::core::objectmodel::BaseContext* ctx, const sofa::core::ConstraintParams* cParams, const TMultiVecId& vid) @@ -132,8 +124,6 @@ void GenericConstraintSolver::init() { ConstraintSolverImpl::init(); - constraintCorrectionIsActive.resize(l_constraintCorrections.size()); - simulation::common::VectorOperations vop(sofa::core::execparams::defaultInstance(), this->getContext()); { sofa::core::behavior::MultiVecDeriv lambda(&vop, m_lambdaId); @@ -170,15 +160,12 @@ void GenericConstraintSolver::cleanup() bool GenericConstraintSolver::prepareStates(const core::ConstraintParams *cParams, MultiVecId /*res1*/, MultiVecId /*res2*/) { - SCOPED_TIMER_VARNAME(vtimer, "PrepareStates"); - last_cp = current_cp; clearConstraintProblemLocks(); // NOTE: this assumes we solve only one constraint problem per step simulation::common::VectorOperations vop(cParams, this->getContext()); - { sofa::core::behavior::MultiVecDeriv lambda(&vop, m_lambdaId); lambda.realloc(&vop,false,true, core::VecIdProperties{"lambda", GetClass()->className}); @@ -199,65 +186,42 @@ bool GenericConstraintSolver::prepareStates(const core::ConstraintParams *cParam return true; } -bool GenericConstraintSolver::buildSystem(const core::ConstraintParams *cParams, MultiVecId /*res1*/, MultiVecId /*res2*/) +bool GenericConstraintSolver::buildSystem(const core::ConstraintParams *cParams, MultiVecId res1, MultiVecId res2) { - unsigned int numConstraints = 0; - - { - SCOPED_TIMER("Accumulate Constraint"); - - auto* context = getContext(); - - // mechanical action executed from root node to propagate the constraints - MechanicalResetConstraintVisitor(cParams).execute(context); - // calling buildConstraintMatrix - MechanicalBuildConstraintMatrix(cParams, cParams->j(), numConstraints).execute(context); - - MechanicalAccumulateMatrixDeriv(cParams, cParams->j(), reverseAccumulateOrder.getValue()).execute(context); - - // suppress the constraints that are on DOFS currently concerned by projective constraint - core::MechanicalParams mparams = core::MechanicalParams(*cParams); - MechanicalProjectJacobianMatrixVisitor(&mparams).execute(context); - } + SOFA_UNUSED(res1); + SOFA_UNUSED(res2); + const unsigned int numConstraints = buildConstraintMatrix(cParams); sofa::helper::AdvancedTimer::valSet("numConstraints", numConstraints); + // suppress the constraints that are on DOFS currently concerned by projective constraint + applyProjectiveConstraintOnConstraintMatrix(cParams); + current_cp->clear(numConstraints); - { - SCOPED_TIMER_VARNAME(getConstraintValueTimer, "Get Constraint Value"); - MechanicalGetConstraintViolationVisitor(cParams, ¤t_cp->dFree).execute(getContext()); - } + getConstraintViolation(cParams, ¤t_cp->dFree); { - SCOPED_TIMER_VARNAME(getConstraintResolutionsTimer, "Get Constraint Resolutions"); + // creates constraint-specific objects used for the constraint resolution + // in a Gauss-Seidel algorithm + SCOPED_TIMER("Get Constraint Resolutions"); MechanicalGetConstraintResolutionVisitor(cParams, current_cp->constraintsResolutions).execute(getContext()); } - msg_info() << numConstraints << " constraints"; - - // Test if the nodes containing the constraint correction are active (not sleeping) - for (unsigned int i = 0; i < l_constraintCorrections.size(); i++) - constraintCorrectionIsActive[i] = !l_constraintCorrections[i]->getContext()->isSleeping(); - // Resolution depending on the method selected switch ( d_resolutionMethod.getValue().getSelectedId() ) { - // ProjectedGaussSeidel - case 0: { + case 0: // ProjectedGaussSeidel + case 2: // NonsmoothNonlinearConjugateGradient + { buildSystem_matrixAssembly(cParams); break; } - // UnbuiltGaussSeidel - case 1: { + case 1: // UnbuiltGaussSeidel + { buildSystem_matrixFree(numConstraints); break; } - // NonsmoothNonlinearConjugateGradient - case 2: { - buildSystem_matrixAssembly(cParams); - break; - } default: msg_error() << "Wrong \"resolutionMethod\" given"; } @@ -366,8 +330,11 @@ void GenericConstraintSolver::buildSystem_matrixAssembly(const core::ConstraintP simulation::TaskScheduler* taskScheduler = simulation::MainTaskSchedulerFactory::createInRegistry(); assert(taskScheduler); + //Used to prevent simultaneous accesses to the main compliance matrix std::mutex mutex; + //Visits all constraint corrections to compute the compliance matrix projected + //in the constraint space. simulation::forEachRange(execution, *taskScheduler, l_constraintCorrections.begin(), l_constraintCorrections.end(), [&cParams, this, &multithreading, &mutex](const auto& range) { @@ -389,41 +356,49 @@ void GenericConstraintSolver::buildSystem_matrixAssembly(const core::ConstraintP dmsg_info() << " computeCompliance_done " ; } -void GenericConstraintSolver::rebuildSystem(SReal massFactor, SReal forceFactor) +void GenericConstraintSolver::rebuildSystem(const SReal massFactor, const SReal forceFactor) { for (const auto& cc : l_constraintCorrections) { - if (!cc->isActive()) continue; - cc->rebuildSystem(massFactor, forceFactor); + if (cc->isActive()) + { + cc->rebuildSystem(massFactor, forceFactor); + } } } void printLCP(std::ostream& file, SReal *q, SReal **M, SReal *f, int dim, bool printMatrix = true) { file.precision(9); - // affichage de la matrice du LCP - if (printMatrix) { + + // print LCP matrix + if (printMatrix) + { file << msgendl << " W = ["; - for(int compteur=0;compteur GenericConstraintSolver::filteredConstraintCorrections() const { - using sofa::helper::AdvancedTimer; - using core::behavior::BaseConstraintCorrection; - - msg_info() << "KeepContactForces done" ; + sofa::type::vector filteredConstraintCorrections; + filteredConstraintCorrections.reserve(l_constraintCorrections.size()); + std::copy_if(l_constraintCorrections.begin(), l_constraintCorrections.end(), + std::back_inserter(filteredConstraintCorrections), + [](const auto& constraintCorrection) + { + return constraintCorrection && + !constraintCorrection->getContext()->isSleeping() && + constraintCorrection->isActive(); + }); + return filteredConstraintCorrections; +} +void GenericConstraintSolver::applyMotionCorrection( + const core::ConstraintParams* cParams, + const core::MultiVecCoordId xId, + const core::MultiVecDerivId vId, + core::behavior::BaseConstraintCorrection* constraintCorrection) const +{ + if (cParams->constOrder() == sofa::core::ConstraintOrder::POS_AND_VEL) { - SCOPED_TIMER("Compute And Apply Motion Correction"); - - if (cParams->constOrder() == core::ConstraintParams::POS_AND_VEL) - { - const core::MultiVecCoordId xId(res1); - const core::MultiVecDerivId vId(res2); - for (unsigned int i = 0; i < l_constraintCorrections.size(); i++) - { - if (!constraintCorrectionIsActive[i]) continue; - BaseConstraintCorrection* cc = l_constraintCorrections[i]; - if (!cc->isActive()) continue; + constraintCorrection->applyMotionCorrection(cParams, xId, vId, cParams->dx(), this->getDx() ); + } + else if (cParams->constOrder() == sofa::core::ConstraintOrder::POS) + { + constraintCorrection->applyPositionCorrection(cParams, xId, cParams->dx(), this->getDx()); + } + else if (cParams->constOrder() == sofa::core::ConstraintOrder::VEL) + { + constraintCorrection->applyVelocityCorrection(cParams, vId, cParams->dx(), this->getDx() ); + } +} - { - helper::ScopedAdvancedTimer computeCorrectonFromLambdaTimer("ComputeCorrection on: " + cc->getName()); - cc->computeMotionCorrectionFromLambda(cParams, this->getDx(), ¤t_cp->f); - } +void GenericConstraintSolver::computeAndApplyMotionCorrection(const core::ConstraintParams* cParams, MultiVecId res1, MultiVecId res2) const +{ + SCOPED_TIMER("Compute And Apply Motion Correction"); - { - helper::ScopedAdvancedTimer applyCorrectonFromLambdaTimer("ApplyCorrection on: " + cc->getName()); - cc->applyMotionCorrection(cParams, xId, vId, cParams->dx(), this->getDx() ); - } - } - } - else if (cParams->constOrder() == core::ConstraintParams::POS) - { - const core::MultiVecCoordId xId(res1); - for (unsigned int i = 0; i < l_constraintCorrections.size(); i++) - { - if (!constraintCorrectionIsActive[i]) continue; - BaseConstraintCorrection* cc = l_constraintCorrections[i]; - if (!cc->isActive()) continue; + static constexpr auto supportedCorrections = { + sofa::core::ConstraintOrder::POS_AND_VEL, + sofa::core::ConstraintOrder::POS, + sofa::core::ConstraintOrder::VEL + }; - { - sofa::helper::ScopedAdvancedTimer computeCorrectionTimer("ComputeCorrection on: " + cc->getName()); - cc->computeMotionCorrectionFromLambda(cParams, this->getDx(), ¤t_cp->f); - } + if (std::find(supportedCorrections.begin(), supportedCorrections.end(), cParams->constOrder()) != supportedCorrections.end()) + { + const core::MultiVecCoordId xId(res1); + const core::MultiVecDerivId vId(cParams->constOrder() == sofa::core::ConstraintOrder::VEL ? res1 : res2); - { - sofa::helper::ScopedAdvancedTimer applyCorrectionTimer("ApplyCorrection on: " + cc->getName()); - cc->applyPositionCorrection(cParams, xId, cParams->dx(), this->getDx()); - } - } - } - else if (cParams->constOrder() == core::ConstraintParams::VEL) + for (const auto& constraintCorrection : filteredConstraintCorrections()) { - const core::MultiVecDerivId vId(res1); - for (unsigned int i = 0; i < l_constraintCorrections.size(); i++) { - if (!constraintCorrectionIsActive[i]) continue; - BaseConstraintCorrection* cc = l_constraintCorrections[i]; - if (!cc->isActive()) continue; - - { - sofa::helper::ScopedAdvancedTimer computeCorrectionTimer("ComputeCorrection on: " + cc->getName()); - cc->computeMotionCorrectionFromLambda(cParams, this->getDx(), ¤t_cp->f); - } - - { - sofa::helper::ScopedAdvancedTimer applyCorrectionTimer("ApplyCorrection on: " + cc->getName()); - cc->applyVelocityCorrection(cParams, vId, cParams->dx(), this->getDx() ); - } + SCOPED_TIMER("ComputeCorrection"); + constraintCorrection->computeMotionCorrectionFromLambda(cParams, this->getDx(), ¤t_cp->f); } + + SCOPED_TIMER("ApplyCorrection"); + applyMotionCorrection(cParams, xId, vId, constraintCorrection); } } +} - msg_info() << "Compute And Apply Motion Correction in constraintCorrection done" ; +void GenericConstraintSolver::storeConstraintLambdas(const core::ConstraintParams* cParams) +{ + SCOPED_TIMER("Store Constraint Lambdas"); - { - SCOPED_TIMER("Store Constraint Lambdas"); + /// Some constraint correction schemes may have written the constraint motion space lambda in the lambdaId VecId. + /// In order to be sure that we are not accumulating things twice, we need to clear. + clearMultiVecId(getContext(), cParams, m_lambdaId); - /// Some constraint correction schemes may have written the constraint motion space lambda in the lambdaId VecId. - /// In order to be sure that we are not accumulating things twice, we need to clear. - clearMultiVecId(getContext(), cParams, m_lambdaId); + /// Store lambda and accumulate. + ConstraintStoreLambdaVisitor v(cParams, ¤t_cp->f); + this->getContext()->executeVisitor(&v); +} - /// Store lambda and accumulate. - ConstraintStoreLambdaVisitor v(cParams, ¤t_cp->f); - this->getContext()->executeVisitor(&v); - } + +bool GenericConstraintSolver::applyCorrection(const core::ConstraintParams *cParams, MultiVecId res1, MultiVecId res2) +{ + computeAndApplyMotionCorrection(cParams, res1, res2); + storeConstraintLambdas(cParams); return true; } @@ -603,10 +572,7 @@ ConstraintProblem* GenericConstraintSolver::getConstraintProblem() void GenericConstraintSolver::clearConstraintProblemLocks() { - for (unsigned int i = 0; i < CP_BUFFER_SIZE; ++i) - { - m_cpIsLocked[i] = false; - } + std::fill(m_cpIsLocked.begin(), m_cpIsLocked.end(), false); } void GenericConstraintSolver::lockConstraintProblem(sofa::core::objectmodel::BaseObject* from, ConstraintProblem* p1, ConstraintProblem* p2) diff --git a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.h b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.h index cb878c135149..0a6189bfddfd 100644 --- a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.h +++ b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/GenericConstraintSolver.h @@ -51,8 +51,6 @@ class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API GenericConstraintSolver : bool prepareStates(const core::ConstraintParams * /*cParams*/, MultiVecId res1, MultiVecId res2=MultiVecId::null()) override; bool buildSystem(const core::ConstraintParams * /*cParams*/, MultiVecId res1, MultiVecId res2=MultiVecId::null()) override; - void buildSystem_matrixFree(unsigned int numConstraints); - void buildSystem_matrixAssembly(const core::ConstraintParams *cParams); void rebuildSystem(SReal massFactor, SReal forceFactor) override; bool solveSystem(const core::ConstraintParams * /*cParams*/, MultiVecId res1, MultiVecId res2=MultiVecId::null()) override; bool applyCorrection(const core::ConstraintParams * /*cParams*/, MultiVecId res1, MultiVecId res2=MultiVecId::null()) override; @@ -104,16 +102,20 @@ class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API GenericConstraintSolver : void clearConstraintProblemLocks(); - enum { CP_BUFFER_SIZE = 10 }; - sofa::type::fixed_array m_cpBuffer; - sofa::type::fixed_array m_cpIsLocked; + static constexpr auto CP_BUFFER_SIZE = 10; + sofa::type::fixed_array m_cpBuffer; + sofa::type::fixed_array m_cpIsLocked; GenericConstraintProblem *current_cp, *last_cp; SOFA_ATTRIBUTE_DISABLED__GENERICCONSTRAINTSOLVER_CONSTRAINTCORRECTIONS() DeprecatedAndRemoved constraintCorrections; //use ConstraintSolverImpl::l_constraintCorrections instead - type::vector constraintCorrectionIsActive; // for each constraint correction, a boolean that is false if the parent node is sleeping sofa::core::MultiVecDerivId m_lambdaId; sofa::core::MultiVecDerivId m_dxId; + void buildSystem_matrixFree(unsigned int numConstraints); + + // Explicitly compute the compliance matrix projected in the constraint space + void buildSystem_matrixAssembly(const core::ConstraintParams *cParams); + private: struct ComplianceWrapper @@ -133,6 +135,17 @@ class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API GenericConstraintSolver : std::unique_ptr m_threadMatrix; }; + + sofa::type::vector filteredConstraintCorrections() const; + + void computeAndApplyMotionCorrection(const core::ConstraintParams* cParams, GenericConstraintSolver::MultiVecId res1, GenericConstraintSolver::MultiVecId res2) const; + void applyMotionCorrection( + const core::ConstraintParams* cParams, + const core::MultiVecCoordId xId, + const core::MultiVecDerivId vId, + core::behavior::BaseConstraintCorrection* constraintCorrection) const; + void storeConstraintLambdas(const core::ConstraintParams* cParams); + }; } //namespace sofa::component::constraint::lagrangian::solver diff --git a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.cpp b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.cpp index 9a44653e3b35..22f7f0437148 100644 --- a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.cpp @@ -31,21 +31,12 @@ #include #include -#include -using sofa::simulation::mechanicalvisitor::MechanicalAccumulateMatrixDeriv; - -#include -using sofa::simulation::mechanicalvisitor::MechanicalBuildConstraintMatrix; - #include using sofa::simulation::mechanicalvisitor::MechanicalGetConstraintInfoVisitor; #include using sofa::simulation::mechanicalvisitor::MechanicalVOpVisitor; -#include -using sofa::simulation::mechanicalvisitor::MechanicalResetConstraintVisitor; - using sofa::core::VecId; namespace sofa::component::constraint::lagrangian::solver @@ -75,8 +66,8 @@ LCPConstraintSolver::LCPConstraintSolver() , showCellWidth( initData(&showCellWidth, "showCellWidth", "Distance between each constraint cells")) , showTranslation( initData(&showTranslation, "showTranslation", "Position of the first cell")) , showLevelTranslation( initData(&showLevelTranslation, "showLevelTranslation", "Translation between levels")) - , lcp(&lcp1) - , last_lcp(nullptr) + , current_cp(&lcp1) + , last_cp(nullptr) , _W(&lcp1.W) , _dFree(&lcp1.dFree) , _result(&lcp1.f) @@ -95,13 +86,6 @@ LCPConstraintSolver::~LCPConstraintSolver() { } -void LCPConstraintSolver::init() -{ - ConstraintSolverImpl::init(); - - constraintCorrectionIsActive.resize(l_constraintCorrections.size()); -} - void LCPConstraintProblem::solveTimed(SReal tolerance, int maxIt, SReal timeout) { helper::nlcp_gaussseidelTimed(dimension, getDfree(), getW(), getF(), mu, tolerance, maxIt, true, timeout); @@ -109,16 +93,13 @@ void LCPConstraintProblem::solveTimed(SReal tolerance, int maxIt, SReal timeout) bool LCPConstraintSolver::prepareStates(const core::ConstraintParams * /*cParams*/, MultiVecId /*res1*/, MultiVecId /*res2*/) { - sofa::helper::AdvancedTimer::StepVar vtimer("PrepareStates"); - - last_lcp = lcp; + last_cp = current_cp; MechanicalVOpVisitor(core::execparams::defaultInstance(), (core::VecId)core::VecDerivId::dx()).setMapped(true).execute( getContext()); //dX=0 msg_info() <<" propagate DXn performed - collision called" ; - SCOPED_TIMER_VARNAME(resetContactForceTimer, "resetContactForce"); - - for (const auto cc : l_constraintCorrections) + SCOPED_TIMER("resetContactForce"); + for (const auto& cc : l_constraintCorrections) { cc->resetContactForce(); } @@ -126,28 +107,45 @@ bool LCPConstraintSolver::prepareStates(const core::ConstraintParams * /*cParams return true; } -bool LCPConstraintSolver::buildSystem(const core::ConstraintParams * /*cParams*/, MultiVecId /*res1*/, MultiVecId /*res2*/) +bool LCPConstraintSolver::buildSystem(const core::ConstraintParams * /*cParams*/, MultiVecId res1, MultiVecId res2) { + SOFA_UNUSED(res1); + SOFA_UNUSED(res2); - // Test if the nodes containing the constraint correction are active (not sleeping) - for (unsigned int i = 0; i < l_constraintCorrections.size(); i++) - { - constraintCorrectionIsActive[i] = !l_constraintCorrections[i]->getContext()->isSleeping(); - } + buildSystem(); + return true; +} - if(build_lcp.getValue()) - { - SCOPED_TIMER_VARNAME(buildTimer, "build_LCP"); - build_LCP(); +void LCPConstraintSolver::buildSystem() +{ + core::ConstraintParams cparams; + + cparams.setX(core::ConstVecCoordId::freePosition()); + cparams.setV(core::ConstVecDerivId::freeVelocity()); + + _numConstraints = buildConstraintMatrix(&cparams); + sofa::helper::AdvancedTimer::valSet("numConstraints", _numConstraints); + + current_cp->mu = mu.getValue(); + current_cp->clear(_numConstraints); + + getConstraintViolation(&cparams, _dFree); + + if (build_lcp.getValue()) + { + addComplianceInConstraintSpace(cparams); } else { - SCOPED_TIMER_VARNAME(buildTimer, "build_problem"); - - build_problem_info(); + // When the LCP or the NLCP is not fully built, the diagonal blocks of the matrix are still needed for the resolution + _Wdiag.resize(_numConstraints,_numConstraints); } - return true; + + buildHierarchy(); + + getConstraintInfo(cparams); + } bool LCPConstraintSolver::solveSystem(const core::ConstraintParams * /*cParams*/, MultiVecId /*res1*/, MultiVecId /*res2*/) @@ -165,7 +163,7 @@ bool LCPConstraintSolver::solveSystem(const core::ConstraintParams * /*cParams*/ if (_mu > 0.0) { - lcp->tolerance = _tol; + current_cp->tolerance = _tol; if (multi_grid.getValue()) { @@ -237,7 +235,7 @@ bool LCPConstraintSolver::solveSystem(const core::ConstraintParams * /*cParams*/ const SReal _tol = tol.getValue(); const int _maxIt = maxIt.getValue(); - build_LCP(); + buildSystem(); helper::nlcp_gaussseidel(_numConstraints, _dFree->ptr(), _W->lptr(), _result->ptr(), _mu, _tol, _maxIt, initial_guess.getValue()); dmsg_info() <<"\n_result nlcp :"<<(*_result); @@ -249,8 +247,8 @@ bool LCPConstraintSolver::solveSystem(const core::ConstraintParams * /*cParams*/ if(d_computeConstraintForces.getValue()) { sofa::helper::WriteOnlyAccessor>> constraints = d_constraintForces; - constraints.resize(lcp->getDimension()); - for(int i=0; igetDimension(); i++) + constraints.resize(current_cp->getDimension()); + for(int i=0; igetDimension(); i++) { constraints[i] = _result->ptr()[i]; } @@ -262,48 +260,22 @@ bool LCPConstraintSolver::solveSystem(const core::ConstraintParams * /*cParams*/ bool LCPConstraintSolver::applyCorrection(const core::ConstraintParams * /*cParams*/, MultiVecId /*res1*/, MultiVecId /*res2*/) { if (initial_guess.getValue()) + { keepContactForcesValue(); + } - dmsg_info() << "keepContactForces done" ; - + SCOPED_TIMER("Apply Contact Force"); + for (const auto& l_constraintCorrection : l_constraintCorrections) { - SCOPED_TIMER("Apply Contact Force"); - for (unsigned int i = 0; i < l_constraintCorrections.size(); i++) + if (!l_constraintCorrection->getContext()->isSleeping()) { - if (!constraintCorrectionIsActive[i]) continue; - core::behavior::BaseConstraintCorrection* cc = l_constraintCorrections[i]; - cc->applyContactForce(_result); + l_constraintCorrection->applyContactForce(_result); } } - dmsg_info() <<"applyContactForce in constraintCorrection done" ; - return true; } -void LCPConstraintSolver::resetConstraints(core::ConstraintParams cparams) -{ - SCOPED_TIMER_VARNAME(resetConstraintsTimer, "Reset Constraint"); - MechanicalResetConstraintVisitor resetCtr(&cparams); - resetCtr.execute(getContext()); -} - -void LCPConstraintSolver::buildConstraintMatrix(core::ConstraintParams cparams) -{ - SCOPED_TIMER_VARNAME(buildConstraintMatrixTimer, "Build Constraint Matrix"); - - MechanicalBuildConstraintMatrix buildConstraintMatrix(&cparams, cparams.j(), _numConstraints ); - buildConstraintMatrix.execute(getContext()); -} - -void LCPConstraintSolver::accumulateMatrixDeriv(core::ConstraintParams cparams) -{ - SCOPED_TIMER_VARNAME(accumulateMatrixDerivTimer, "Accumulate Matrix Deriv"); - - MechanicalAccumulateMatrixDeriv accumulateMatrixDeriv(&cparams, cparams.j()); - accumulateMatrixDeriv.execute(getContext()); -} - void LCPConstraintSolver::buildHierarchy() { int nLevels = 1; @@ -336,7 +308,9 @@ void LCPConstraintSolver::getConstraintInfo(core::ConstraintParams cparams) MechanicalGetConstraintInfoVisitor(&cparams, hierarchy_constraintBlockInfo[0], hierarchy_constraintIds[0], hierarchy_constraintPositions[0], hierarchy_constraintDirections[0], hierarchy_constraintAreas[0]).execute(getContext()); } if (initial_guess.getValue()) + { computeInitialGuess(); + } } } @@ -344,52 +318,16 @@ void LCPConstraintSolver::addComplianceInConstraintSpace(core::ConstraintParams { SCOPED_TIMER("Get Compliance"); - dmsg_info() <<" computeCompliance in " << l_constraintCorrections.size()<< " constraintCorrections" ; + dmsg_info() <<" computeCompliance in " << l_constraintCorrections.size() << " constraintCorrections" ; - for (unsigned int i=0; iaddComplianceInConstraintSpace(&cparams, _W); } dmsg_info() << "W=" << *_W ; } -void LCPConstraintSolver::build_LCP() -{ - _numConstraints = 0; - core::ConstraintParams cparams; - - cparams.setX(core::ConstVecCoordId::freePosition()); - cparams.setV(core::ConstVecDerivId::freeVelocity()); - - resetConstraints(cparams); - - buildConstraintMatrix(cparams); - - accumulateMatrixDeriv(cparams); - - const auto _mu = mu.getValue(); - - sofa::helper::AdvancedTimer::valSet("numConstraints", _numConstraints); - - lcp->mu = _mu; - lcp->clear(_numConstraints); - - { - SCOPED_TIMER_VARNAME(getConstraintValueTimer, "Get Constraint Value"); - MechanicalGetConstraintViolationVisitor(&cparams, _dFree).execute(getContext()); - } - - dmsg_info() << _numConstraints << " constraints, mu = "<<_mu; - - addComplianceInConstraintSpace(cparams); - - buildHierarchy(); - - getConstraintInfo(cparams); -} - void LCPConstraintSolver::build_Coarse_Compliance(std::vector &constraint_merge, int sizeCoarseSystem) { /* constraint_merge => tableau donne l'indice du groupe de contraintes dans le système grossier en fonction de l'indice de la contrainte dans le système de départ */ @@ -697,47 +635,6 @@ void LCPConstraintSolver::MultigridConstraintsMerge_Spatial() } } - -/// build_problem_info -/// When the LCP or the NLCP is not fully built, the diagonal blocks of the matrix are still needed for the resolution -/// This function ask to the constraintCorrection classes to build this diagonal blocks -void LCPConstraintSolver::build_problem_info() -{ - core::ConstraintParams cparams; - - cparams.setX(core::ConstVecCoordId::freePosition()); - cparams.setV(core::ConstVecDerivId::freeVelocity()); - - _numConstraints = 0; - - resetConstraints(cparams); - - buildConstraintMatrix(cparams); - - accumulateMatrixDeriv(cparams); - - const auto _mu = mu.getValue(); - - sofa::helper::AdvancedTimer::valSet("numConstraints", _numConstraints); - - lcp->mu = _mu; - lcp->clear(_numConstraints); - - // as _Wdiag is a sparse matrix resize do not allocate memory - _Wdiag.resize(_numConstraints,_numConstraints); - - { - SCOPED_TIMER_VARNAME(getConstraintValueTimer, "Get Constraint Value"); - MechanicalGetConstraintViolationVisitor(&cparams, _dFree).execute(getContext()); - } - - dmsg_info() << _numConstraints << " constraints, mu = "<<_mu; - - buildHierarchy(); - - getConstraintInfo(cparams); -} - void LCPConstraintSolver::computeInitialGuess() { sofa::helper::AdvancedTimer::StepVar vtimer("InitialGuess"); @@ -1281,25 +1178,25 @@ int LCPConstraintSolver::lcp_gaussseidel_unbuilt(SReal *dfree, SReal *f, std::ve ConstraintProblem* LCPConstraintSolver::getConstraintProblem() { - return last_lcp; + return last_cp; } void LCPConstraintSolver::lockConstraintProblem(sofa::core::objectmodel::BaseObject* /*from*/, ConstraintProblem* l1, ConstraintProblem* l2) { - if((lcp!=l1)&&(lcp!=l2)) // Le lcp courant n'est pas locké + if((current_cp!=l1)&&(current_cp!=l2)) // Le lcp courant n'est pas locké return; if((&lcp1!=l1)&&(&lcp1!=l2)) // lcp1 n'est pas locké - lcp = &lcp1; + current_cp = &lcp1; else if((&lcp2!=l1)&&(&lcp2!=l2)) // lcp2 n'est pas locké - lcp = &lcp2; + current_cp = &lcp2; else - lcp = &lcp3; // lcp1 et lcp2 sont lockés, donc lcp3 n'est pas locké + current_cp = &lcp3; // lcp1 et lcp2 sont lockés, donc lcp3 n'est pas locké // Mise � jour de _W _dFree et _result - _W = &lcp->W; - _dFree = &lcp->dFree; - _result = &lcp->f; + _W = ¤t_cp->W; + _dFree = ¤t_cp->dFree; + _result = ¤t_cp->f; } diff --git a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.h b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.h index 14320ffad080..38dc4f782717 100644 --- a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.h +++ b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.h @@ -39,7 +39,7 @@ namespace sofa::component::constraint::lagrangian::solver { -class LCPConstraintProblem : public ConstraintProblem +class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API LCPConstraintProblem : public ConstraintProblem { public: SReal mu; @@ -65,7 +65,6 @@ class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API LCPConstraintSolver : publ */ ~LCPConstraintSolver() override; public: - void init() override; bool prepareStates(const core::ConstraintParams * /*cParams*/, MultiVecId res1, MultiVecId res2=MultiVecId::null()) override; bool buildSystem(const core::ConstraintParams * /*cParams*/, MultiVecId res1, MultiVecId res2=MultiVecId::null()) override; @@ -104,19 +103,12 @@ class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API LCPConstraintSolver : publ void lockConstraintProblem(sofa::core::objectmodel::BaseObject* from, ConstraintProblem* p1, ConstraintProblem* p2=nullptr) override; ///< Do not use the following LCPs until the next call to this function. This is used to prevent concurent access to the LCP when using a LCPForceFeedback through an haptic thread private: - type::vector constraintCorrectionIsActive; // for each constraint correction, a boolean that is false if the parent node is sleeping void computeInitialGuess(); void keepContactForcesValue(); unsigned int _numConstraints; SOFA_ATTRIBUTE_DEPRECATED__LCPCONSTRAINTSOLVERMUMEMBER() DeprecatedAndRemoved _mu; - /// Call the method resetConstraint on all the mechanical states and BaseConstraintSet - void resetConstraints(core::ConstraintParams cparams); - /// Call the method buildConstraintMatrix on all the BaseConstraintSet - void buildConstraintMatrix(core::ConstraintParams cparams); - /// Call the method applyJT on all the mappings - void accumulateMatrixDeriv(core::ConstraintParams cparams); /// Multigrid hierarchy is resized and cleared void buildHierarchy(); /// Call the method getConstraintInfo on all the BaseConstraintSet @@ -125,9 +117,8 @@ class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API LCPConstraintSolver : publ void addComplianceInConstraintSpace(core::ConstraintParams cparams); /// for built lcp /// - void build_LCP(); LCPConstraintProblem lcp1, lcp2, lcp3; // Triple buffer for LCP. - LCPConstraintProblem *lcp, *last_lcp; /// use of last_lcp allows several LCPForceFeedback to be used in the same scene + LCPConstraintProblem *current_cp, *last_cp; /// use of last_lcp allows several LCPForceFeedback to be used in the same scene sofa::linearalgebra::LPtrFullMatrix *_W; /// multi-grid approach /// @@ -145,10 +136,10 @@ class SOFA_COMPONENT_CONSTRAINT_LAGRANGIAN_SOLVER_API LCPConstraintSolver : publ /// common built-unbuilt sofa::linearalgebra::FullVector *_dFree, *_result; + void buildSystem(); /// /// for unbuilt lcp /// - void build_problem_info(); int lcp_gaussseidel_unbuilt(SReal *dfree, SReal *f, std::vector* residuals = nullptr); int nlcp_gaussseidel_unbuilt(SReal *dfree, SReal *f, std::vector* residuals = nullptr); int gaussseidel_unbuilt(SReal *dfree, SReal *f, std::vector* residuals = nullptr); diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/EulerImplicitSolver.cpp b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/EulerImplicitSolver.cpp index abe7c9cc798e..f0b2cab56cb3 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/EulerImplicitSolver.cpp +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/EulerImplicitSolver.cpp @@ -192,7 +192,7 @@ void EulerImplicitSolver::solve(const core::ExecParams* params, SReal dt, sofa:: if (solveConstraint) { SOFATIMER_NEXTSTEP("CorrectV"); - mop.solveConstraint(newVel,core::ConstraintParams::VEL); + mop.solveConstraint(newVel,core::ConstraintOrder::VEL); } SOFATIMER_NEXTSTEP("UpdateX"); @@ -201,7 +201,7 @@ void EulerImplicitSolver::solve(const core::ExecParams* params, SReal dt, sofa:: if (solveConstraint) { SOFATIMER_NEXTSTEP("CorrectX"); - mop.solveConstraint(newPos,core::ConstraintParams::POS); + mop.solveConstraint(newPos,core::ConstraintOrder::POS); } #undef SOFATIMER_NEXTSTEP sofa::helper::AdvancedTimer::stepEnd (prevStep); @@ -218,7 +218,7 @@ void EulerImplicitSolver::solve(const core::ExecParams* params, SReal dt, sofa:: if (solveConstraint) { SOFATIMER_NEXTSTEP("CorrectV"); - mop.solveConstraint(newVel,core::ConstraintParams::VEL); + mop.solveConstraint(newVel,core::ConstraintOrder::VEL); } SOFATIMER_NEXTSTEP("UpdateX"); @@ -228,7 +228,7 @@ void EulerImplicitSolver::solve(const core::ExecParams* params, SReal dt, sofa:: if (solveConstraint) { SOFATIMER_NEXTSTEP("CorrectX"); - mop.solveConstraint(newPos,core::ConstraintParams::POS); + mop.solveConstraint(newPos,core::ConstraintOrder::POS); } #undef SOFATIMER_NEXTSTEP sofa::helper::AdvancedTimer::stepEnd (prevStep); @@ -266,11 +266,11 @@ void EulerImplicitSolver::solve(const core::ExecParams* params, SReal dt, sofa:: { { SCOPED_TIMER_VARNAME(correctVTimer, "CorrectV"); - mop.solveConstraint(newVel,core::ConstraintParams::VEL); + mop.solveConstraint(newVel,core::ConstraintOrder::VEL); } { SCOPED_TIMER_VARNAME(correctXTimer, "CorrectX"); - mop.solveConstraint(newPos,core::ConstraintParams::POS); + mop.solveConstraint(newPos,core::ConstraintOrder::POS); } } } diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.cpp b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.cpp index 0d4b9818b8f8..be829e69fb60 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.cpp +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.cpp @@ -138,11 +138,11 @@ void NewmarkImplicitSolver::solve(const core::ExecParams* params, SReal dt, sofa b.eq(vel, a, h*(0.5-beta)); b.peq(aResult, h*beta); newPos.eq(pos, b, h); - solveConstraint(dt,xResult,core::ConstraintParams::POS); + solveConstraint(dt,xResult,core::ConstraintParams::ConstOrder::POS); // v_{t+h} = v_t + h ( (1-\gamma) a_t + \gamma a_{t+h} ) newVel.eq(vel, a, h*(1-gamma)); newVel.peq(aResult, h*gamma); - solveConstraint(dt,vResult,core::ConstraintParams::VEL); + solveConstraint(dt,vResult,core::ConstraintParams::ConstOrder::VEL); #else // single-operation optimization typedef core::behavior::BaseMechanicalState::VMultiOp VMultiOp; @@ -160,8 +160,8 @@ void NewmarkImplicitSolver::solve(const core::ExecParams* params, SReal dt, sofa ops[1].second.push_back(std::make_pair(aResult.id(),h*gamma));//v(t+h)=vt+at*h*(1-gamma)+a(t+h)*h*gamma vop.v_multiop(ops); - mop.solveConstraint(vResult,core::ConstraintParams::VEL); - mop.solveConstraint(xResult,core::ConstraintParams::POS); + mop.solveConstraint(vResult,core::ConstraintOrder::VEL); + mop.solveConstraint(xResult,core::ConstraintOrder::POS); #endif diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp index d3d8413877c3..04679365b1a3 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/StaticSolver.cpp @@ -240,7 +240,7 @@ void StaticSolver::solve(const sofa::core::ExecParams* params, SReal dt, sofa::c // Calls "solveConstraint" method of every ConstraintSolver objects found in the current context tree. // todo(jnbrunet): Shouldn't this be done AFTER the position propagation of the mapped nodes? - mop.solveConstraint(x, sofa::core::ConstraintParams::POS); + mop.solveConstraint(x, sofa::core::ConstraintOrder::POS); // Propagate positions to mapped mechanical objects, for example, identity mappings, barycentric mappings, ... // This will call the methods apply and applyJ on every mechanical mappings. diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/VariationalSymplecticSolver.cpp b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/VariationalSymplecticSolver.cpp index ce068ad3e7d2..3ebae89c8599 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/VariationalSymplecticSolver.cpp +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/VariationalSymplecticSolver.cpp @@ -142,7 +142,7 @@ void VariationalSymplecticSolver::solve(const core::ExecParams* params, SReal dt mop.projectResponse(acc); - mop.solveConstraint(acc, core::ConstraintParams::ACC); + mop.solveConstraint(acc, core::ConstraintOrder::ACC); VMultiOp ops; ops.resize(2); @@ -158,7 +158,7 @@ void VariationalSymplecticSolver::solve(const core::ExecParams* params, SReal dt newp.clear(); mop.addMdx(newp,vel_1,1.0); - mop.solveConstraint(vel_1,core::ConstraintParams::VEL); + mop.solveConstraint(vel_1,core::ConstraintOrder::VEL); } else { @@ -270,7 +270,7 @@ void VariationalSymplecticSolver::solve(const core::ExecParams* params, SReal dt vop.v_multiop(opsfin); sofa::helper::AdvancedTimer::stepBegin("CorrectV"); - mop.solveConstraint(vel_1,core::ConstraintParams::VEL); + mop.solveConstraint(vel_1,core::ConstraintOrder::VEL); // update position VMultiOp opsx; @@ -341,7 +341,7 @@ void VariationalSymplecticSolver::solve(const core::ExecParams* params, SReal dt sofa::helper::AdvancedTimer::stepEnd("CorrectV"); { SCOPED_TIMER("CorrectX"); - mop.solveConstraint(x_1,core::ConstraintParams::POS); + mop.solveConstraint(x_1,core::ConstraintOrder::POS); } // update the previous momemtum as the current one for next step diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/CentralDifferenceSolver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/CentralDifferenceSolver.cpp index bc1c3fd65428..06b9d39d42c0 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/CentralDifferenceSolver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/CentralDifferenceSolver.cpp @@ -97,15 +97,15 @@ void CentralDifferenceSolver::solve(const core::ExecParams* params, SReal dt, so mop.accFromF(dx, f); // dx = M^{-1} ( P_n - K u_n ) mop.projectResponse(dx); // dx is projected to the constrained space - mop.solveConstraint(dx, core::ConstraintParams::ACC); + mop.solveConstraint(dx, core::ConstraintOrder::ACC); // apply the solution if (r==0) { #ifdef SOFA_NO_VMULTIOP // unoptimized version vel2.eq( vel, dx, dt ); // vel = vel + dt M^{-1} ( P_n - K u_n ) - mop.solveConstraint(vel2, core::ConstraintParams::VEL); + mop.solveConstraint(vel2, core::ConstraintParams::ConstOrder::VEL); pos2.eq( pos, vel2, dt ); // pos = pos + h vel - mop.solveConstraint(pos2, core::ConstraintParams::POS); + mop.solveConstraint(pos2, core::ConstraintParams::ConstOrder::POS); #else // single-operation optimization @@ -123,8 +123,8 @@ void CentralDifferenceSolver::solve(const core::ExecParams* params, SReal dt, so vop.v_multiop(ops); - mop.solveConstraint(vel2,core::ConstraintParams::VEL); - mop.solveConstraint(pos2,core::ConstraintParams::POS); + mop.solveConstraint(vel2,core::ConstraintOrder::VEL); + mop.solveConstraint(pos2,core::ConstraintOrder::POS); #endif } else @@ -149,8 +149,8 @@ void CentralDifferenceSolver::solve(const core::ExecParams* params, SReal dt, so vop.v_multiop(ops); - mop.solveConstraint(vel2,core::ConstraintParams::VEL); - mop.solveConstraint(pos2,core::ConstraintParams::POS); + mop.solveConstraint(vel2,core::ConstraintOrder::VEL); + mop.solveConstraint(pos2,core::ConstraintOrder::POS); #endif } diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp index 2034f387084f..59a9e6d7f90f 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp @@ -135,10 +135,10 @@ void EulerExplicitSolver::updateState(sofa::simulation::common::VectorOperations //newPos = pos + newVel * dt newVel.eq(vel, acc.id(), dt); - mop->solveConstraint(newVel, core::ConstraintParams::VEL); + mop->solveConstraint(newVel, core::ConstraintParams::ConstOrder::VEL); newPos.eq(pos, newVel, dt); - mop->solveConstraint(newPos, core::ConstraintParams::POS); + mop->solveConstraint(newPos, core::ConstraintParams::ConstOrder::POS); } else { @@ -146,10 +146,10 @@ void EulerExplicitSolver::updateState(sofa::simulation::common::VectorOperations //newVel = vel + acc * dt newPos.eq(pos, vel, dt); - mop->solveConstraint(newPos, core::ConstraintParams::POS); + mop->solveConstraint(newPos, core::ConstraintParams::ConstOrder::POS); newVel.eq(vel, acc.id(), dt); - mop->solveConstraint(newVel, core::ConstraintParams::VEL); + mop->solveConstraint(newVel, core::ConstraintParams::ConstOrder::VEL); } #else // single-operation optimization { @@ -204,8 +204,8 @@ void EulerExplicitSolver::updateState(sofa::simulation::common::VectorOperations vop->v_multiop(ops); // Calls "solveConstraint" on every ConstraintSolver objects found in the current context tree. - mop->solveConstraint(newVel,core::ConstraintParams::VEL); - mop->solveConstraint(newPos,core::ConstraintParams::POS); + mop->solveConstraint(newVel,core::ConstraintOrder::VEL); + mop->solveConstraint(newPos,core::ConstraintOrder::POS); } #endif } @@ -307,7 +307,7 @@ void EulerExplicitSolver::solveConstraints(sofa::simulation::common::MechanicalO SCOPED_TIMER("solveConstraint"); // Calls "solveConstraint" method of every ConstraintSolver objects found in the current context tree. - mop->solveConstraint(acc, core::ConstraintParams::ACC); + mop->solveConstraint(acc, core::ConstraintOrder::ACC); } void EulerExplicitSolver::assembleSystemMatrix(core::behavior::MultiMatrix* matrix) diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta2Solver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta2Solver.cpp index 630e39b069f7..0b3eb389aeed 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta2Solver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta2Solver.cpp @@ -91,9 +91,9 @@ void RungeKutta2Solver::solve(const core::ExecParams* params, SReal dt, sofa::co // Use the derivative at newX, newV to update the state #ifdef SOFA_NO_VMULTIOP // unoptimized version pos2.eq(pos,newV,dt); - solveConstraint(dt,pos2,core::ConstraintParams::POS); + solveConstraint(dt,pos2,core::ConstraintParams::ConstOrder::POS); vel2.eq(vel,acc,dt); - solveConstraint(dt,vel2,core::ConstraintParams::VEL); + solveConstraint(dt,vel2,core::ConstraintParams::ConstOrder::VEL); #else // single-operation optimization { typedef core::behavior::BaseMechanicalState::VMultiOp VMultiOp; @@ -107,8 +107,8 @@ void RungeKutta2Solver::solve(const core::ExecParams* params, SReal dt, sofa::co ops[1].second.push_back(std::make_pair(acc.id(),dt)); vop.v_multiop(ops); - mop.solveConstraint(vel2,core::ConstraintParams::VEL); - mop.solveConstraint(pos2,core::ConstraintParams::POS); + mop.solveConstraint(vel2,core::ConstraintOrder::VEL); + mop.solveConstraint(pos2,core::ConstraintOrder::POS); } #endif diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta4Solver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta4Solver.cpp index 16b72a64bcfb..30ec32ed5555 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta4Solver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta4Solver.cpp @@ -160,9 +160,9 @@ void RungeKutta4Solver::solve(const core::ExecParams* params, SReal dt, sofa::co pos2.peq(k3v,stepBy3); vel2.peq(k3a,stepBy3); pos2.peq(k4v,stepBy6); - solveConstraint(dt, pos2, core::ConstraintParams::POS); + solveConstraint(dt, pos2, core::ConstraintParams::ConstOrder::POS); vel2.peq(k4a,stepBy6); - solveConstraint(dt, vel2, core::ConstraintParams::VEL); + solveConstraint(dt, vel2, core::ConstraintParams::ConstOrder::VEL); #else // single-operation optimization { typedef core::behavior::BaseMechanicalState::VMultiOp VMultiOp; @@ -182,8 +182,8 @@ void RungeKutta4Solver::solve(const core::ExecParams* params, SReal dt, sofa::co ops[1].second.push_back(std::make_pair(k4a.id(),stepBy6)); vop.v_multiop(ops); - mop.solveConstraint(pos, core::ConstraintParams::POS); - mop.solveConstraint(vel, core::ConstraintParams::VEL); + mop.solveConstraint(pos, core::ConstraintOrder::POS); + mop.solveConstraint(vel, core::ConstraintOrder::VEL); } #endif } diff --git a/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MechanicalObject.inl b/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MechanicalObject.inl index 457787a8e4ac..fc0ed06fb5bf 100644 --- a/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MechanicalObject.inl +++ b/Sofa/Component/StateContainer/src/sofa/component/statecontainer/MechanicalObject.inl @@ -2287,9 +2287,11 @@ void MechanicalObject::resetAcc(const core::ExecParams* params, core: template void MechanicalObject::resetConstraint(const core::ConstraintParams* cParams) { + //reset the constraint jacobian matrix Data& c_data = *this->write(cParams->j().getId(this)); sofa::helper::getWriteOnlyAccessor(c_data)->clear(); + //reset the mapping jacobian matrix Data& m_data = *this->write(core::MatrixDerivId::mappingJacobian()); sofa::helper::getWriteOnlyAccessor(m_data)->clear(); } diff --git a/Sofa/framework/Core/CMakeLists.txt b/Sofa/framework/Core/CMakeLists.txt index f21bf8cb32a0..88e44c0829cf 100644 --- a/Sofa/framework/Core/CMakeLists.txt +++ b/Sofa/framework/Core/CMakeLists.txt @@ -17,6 +17,7 @@ set(HEADER_FILES ${SRC_ROOT}/CollisionModel.h ${SRC_ROOT}/ComponentLibrary.h ${SRC_ROOT}/ComponentNameHelper.h + ${SRC_ROOT}/ConstraintOrder.h ${SRC_ROOT}/ConstraintParams.h ${SRC_ROOT}/DataEngine.h ${SRC_ROOT}/DataTracker.h diff --git a/Sofa/framework/Core/src/sofa/core/ConstraintOrder.h b/Sofa/framework/Core/src/sofa/core/ConstraintOrder.h new file mode 100644 index 000000000000..d239203fc033 --- /dev/null +++ b/Sofa/framework/Core/src/sofa/core/ConstraintOrder.h @@ -0,0 +1,57 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#pragma once + +namespace sofa::core +{ + +/// Description of the order of the constraint +enum class ConstraintOrder +{ + POS = 0, + VEL, + ACC, + POS_AND_VEL +}; + +constexpr static std::string_view constOrderToString(ConstraintOrder order) +{ + if (order == sofa::core::ConstraintOrder::POS) + { + return "POSITION"; + } + if (order == sofa::core::ConstraintOrder::VEL) + { + return "VELOCITY"; + } + if (order == sofa::core::ConstraintOrder::ACC) + { + return "ACCELERATION"; + } + if (order == sofa::core::ConstraintOrder::POS_AND_VEL) + { + return "POSITION AND VELOCITY"; + } + return {}; +} + +} diff --git a/Sofa/framework/Core/src/sofa/core/ConstraintParams.cpp b/Sofa/framework/Core/src/sofa/core/ConstraintParams.cpp index 1a98e3d963bf..c88cc51d8f5a 100644 --- a/Sofa/framework/Core/src/sofa/core/ConstraintParams.cpp +++ b/Sofa/framework/Core/src/sofa/core/ConstraintParams.cpp @@ -38,7 +38,7 @@ ConstraintParams::ConstraintParams(const sofa::core::ExecParams& p) , m_j(MatrixDerivId::constraintJacobian()) , m_dx(VecDerivId::dx()) , m_lambda(VecDerivId::externalForce()) - , m_constOrder (POS_AND_VEL) + , m_constOrder (ConstraintOrder::POS_AND_VEL) , m_smoothFactor (1) { } diff --git a/Sofa/framework/Core/src/sofa/core/ConstraintParams.h b/Sofa/framework/Core/src/sofa/core/ConstraintParams.h index 30f7a21d80e6..dcb7ecdb50a7 100644 --- a/Sofa/framework/Core/src/sofa/core/ConstraintParams.h +++ b/Sofa/framework/Core/src/sofa/core/ConstraintParams.h @@ -23,6 +23,7 @@ #include #include #include +#include namespace sofa::core { @@ -34,48 +35,26 @@ class SOFA_CORE_API ConstraintParams : public sofa::core::ExecParams { public: - /// Description of the order of the constraint - enum ConstOrder - { - POS = 0, - VEL, - ACC, - POS_AND_VEL - }; + SOFA_ATTRIBUTE_DEPRECATED__CONSTORDER() static constexpr auto POS = sofa::core::ConstraintOrder::POS; + SOFA_ATTRIBUTE_DEPRECATED__CONSTORDER() static constexpr auto VEL = sofa::core::ConstraintOrder::VEL; + SOFA_ATTRIBUTE_DEPRECATED__CONSTORDER() static constexpr auto ACC = sofa::core::ConstraintOrder::ACC; + SOFA_ATTRIBUTE_DEPRECATED__CONSTORDER() static constexpr auto POS_AND_VEL = sofa::core::ConstraintOrder::POS_AND_VEL; /// @name Flags and parameters getters /// @{ - ConstOrder constOrder() const { return m_constOrder; } + ConstraintOrder constOrder() const { return m_constOrder; } - ConstraintParams& setOrder(ConstOrder o) { m_constOrder = o; return *this; } + ConstraintParams& setOrder(ConstraintOrder o) { m_constOrder = o; return *this; } /// Smooth contribution factor (for smooth constraints resolution) double smoothFactor() const { return m_smoothFactor; } /// @} - std::string getName() const + [[nodiscard]] std::string_view getName() const { - std::string result; - switch ( m_constOrder ) - { - case POS : - result += "POSITION"; - break; - case VEL : - result += "VELOCITY"; - break; - case ACC : - result += "ACCELERATION"; - break; - case POS_AND_VEL : - result += "POSITION AND VELOCITY"; - break; - default : - assert(false); - } - return result; + return constOrderToString(m_constOrder); } /// @name Access to vectors from a given state container (i.e. State or MechanicalState) @@ -166,19 +145,29 @@ class SOFA_CORE_API ConstraintParams : public sofa::core::ExecParams /// Set smooth contribution factor (for smooth constraints resolution) ConstraintParams& setSmoothFactor(double v) { m_smoothFactor = v; return *this; } + /// Returns ids of the position vectors const ConstMultiVecCoordId& x() const { return m_x; } + /// Returns ids of the position vectors ConstMultiVecCoordId& x() { return m_x; } + /// Returns ids of the velocity vectors const ConstMultiVecDerivId& v() const { return m_v; } + /// Returns ids of the velocity vectors ConstMultiVecDerivId& v() { return m_v; } + /// Returns ids of the constraint jacobian matrices const MultiMatrixDerivId& j() const { return m_j; } + /// Returns ids of the constraint jacobian matrices MultiMatrixDerivId& j() { return m_j; } + /// Returns ids of the contraint correction vectors const MultiVecDerivId& dx() const { return m_dx; } + /// Returns ids of the contraint correction vectors MultiVecDerivId& dx() { return m_dx; } + /// Returns ids of the constraint lambda vectors const MultiVecDerivId& lambda() const { return m_lambda; } + /// Returns ids of the constraint lambda vectors MultiVecDerivId& lambda() { return m_lambda; } /// Set the IDs where to read the free position vector @@ -239,7 +228,7 @@ class SOFA_CORE_API ConstraintParams : public sofa::core::ExecParams MultiVecDerivId m_lambda; /// Description of the order of the constraint - ConstOrder m_constOrder; + ConstraintOrder m_constOrder; /// Smooth contribution factor (for smooth constraints resolution) double m_smoothFactor; diff --git a/Sofa/framework/Core/src/sofa/core/behavior/BaseConstraintCorrection.h b/Sofa/framework/Core/src/sofa/core/behavior/BaseConstraintCorrection.h index 872593ba81cf..e7a57ae88d28 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/BaseConstraintCorrection.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/BaseConstraintCorrection.h @@ -112,11 +112,8 @@ class SOFA_CORE_API BaseConstraintCorrection : public virtual objectmodel::BaseO /// the result is accumulated in Vecid::force() virtual void computeResidual(const core::ExecParams* /*params*/, linearalgebra::BaseVector * /*lambda*/) ; - /// @name Deprecated API - /// @{ virtual void applyContactForce(const linearalgebra::BaseVector *f) = 0; virtual void resetContactForce() = 0; - /// @} /// @name Unbuilt constraint system during resolution /// @{ diff --git a/Sofa/framework/Core/src/sofa/core/behavior/ConstraintSolver.cpp b/Sofa/framework/Core/src/sofa/core/behavior/ConstraintSolver.cpp index 39c868111714..f20198c898fa 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/ConstraintSolver.cpp +++ b/Sofa/framework/Core/src/sofa/core/behavior/ConstraintSolver.cpp @@ -33,36 +33,11 @@ ConstraintSolver::~ConstraintSolver() = default; void ConstraintSolver::solveConstraint(const ConstraintParams * cParams, MultiVecId res1, MultiVecId res2) { - const std::string className = "SolveConstraint: " + cParams->getName(); - sofa::helper::ScopedAdvancedTimer solveConstraintTimer(className); - - bool continueSolving = true; - { - helper::ScopedAdvancedTimer timer(className + " - PrepareState"); - continueSolving = prepareStates(cParams, res1, res2); - } - - if (continueSolving) - { - helper::ScopedAdvancedTimer timer(className + " - BuildSystem"); - continueSolving = buildSystem(cParams, res1, res2); - - postBuildSystem(cParams); - } - - if (continueSolving) - { - helper::ScopedAdvancedTimer timer(className + " - SolveSystem"); - continueSolving = solveSystem(cParams, res1, res2); - - postSolveSystem(cParams); - } - - if (continueSolving) - { - helper::ScopedAdvancedTimer timer(className + " - ApplyCorrection"); - applyCorrection(cParams, res1, res2); - } + SCOPED_TIMER("SolveConstraint"); + prepareStatesTask(cParams, res1, res2) && + buildSystemTask(cParams, res1, res2) && + solveSystemTask(cParams, res1, res2) && + applyCorrectionTask(cParams, res1, res2); } bool ConstraintSolver::insertInNode( objectmodel::BaseNode* node ) @@ -79,5 +54,33 @@ bool ConstraintSolver::removeInNode( objectmodel::BaseNode* node ) return true; } +bool ConstraintSolver::prepareStatesTask(const ConstraintParams* cParams, MultiVecId res1, MultiVecId res2) +{ + SCOPED_TIMER("PrepareState"); + return prepareStates(cParams, res1, res2); +} + +bool ConstraintSolver::buildSystemTask(const ConstraintParams* cParams, MultiVecId res1, MultiVecId res2) +{ + SCOPED_TIMER("BuildSystem"); + const auto success = buildSystem(cParams, res1, res2); + postBuildSystem(cParams); + return success; +} + +bool ConstraintSolver::solveSystemTask(const ConstraintParams* cParams, MultiVecId res1, MultiVecId res2) +{ + SCOPED_TIMER("SolveSystem"); + const auto success = solveSystem(cParams, res1, res2); + postSolveSystem(cParams); + return success; +} + +bool ConstraintSolver::applyCorrectionTask(const ConstraintParams* cParams, MultiVecId res1, MultiVecId res2) +{ + SCOPED_TIMER("ApplyCorrection"); + return applyCorrection(cParams, res1, res2); +} + } // namespace sofa::core::behavior diff --git a/Sofa/framework/Core/src/sofa/core/behavior/ConstraintSolver.h b/Sofa/framework/Core/src/sofa/core/behavior/ConstraintSolver.h index 5b4f130dafeb..8c43b5258d6e 100644 --- a/Sofa/framework/Core/src/sofa/core/behavior/ConstraintSolver.h +++ b/Sofa/framework/Core/src/sofa/core/behavior/ConstraintSolver.h @@ -120,6 +120,12 @@ class SOFA_CORE_API ConstraintSolver : public virtual objectmodel::BaseObject virtual void postBuildSystem(const ConstraintParams* constraint_params) { SOFA_UNUSED(constraint_params); } virtual void postSolveSystem(const ConstraintParams* constraint_params) { SOFA_UNUSED(constraint_params); } + + bool prepareStatesTask(const ConstraintParams*, MultiVecId res1, MultiVecId res2); + bool buildSystemTask(const ConstraintParams *, MultiVecId res1, MultiVecId res2); + bool solveSystemTask(const ConstraintParams *, MultiVecId res1, MultiVecId res2); + bool applyCorrectionTask(const ConstraintParams *, MultiVecId res1, MultiVecId res2); + }; } // namespace sofa::core::behavior diff --git a/Sofa/framework/Core/src/sofa/core/config.h.in b/Sofa/framework/Core/src/sofa/core/config.h.in index 023b7858c918..49e8bbe47eb6 100644 --- a/Sofa/framework/Core/src/sofa/core/config.h.in +++ b/Sofa/framework/Core/src/sofa/core/config.h.in @@ -53,3 +53,10 @@ SOFA_ATTRIBUTE_DEPRECATED("v23.12 (PR#3861)", "v24.06", msg) #endif + +#ifdef SOFA_BUILD_SOFA_CORE +#define SOFA_ATTRIBUTE_DEPRECATED__CONSTORDER() +#else +#define SOFA_ATTRIBUTE_DEPRECATED__CONSTORDER() \ + SOFA_ATTRIBUTE_DEPRECATED("v23.12", "v24.06", "ConstOrder is now a scoped enumeration. It must be used to access the values.") +#endif diff --git a/Sofa/framework/Helper/src/sofa/helper/LCPcalc.cpp b/Sofa/framework/Helper/src/sofa/helper/LCPcalc.cpp index 9ad648826e27..492e724a9ed1 100644 --- a/Sofa/framework/Helper/src/sofa/helper/LCPcalc.cpp +++ b/Sofa/framework/Helper/src/sofa/helper/LCPcalc.cpp @@ -1629,11 +1629,11 @@ int nlcp_gaussseidel(int dim, SReal *dfree, SReal**W, SReal *f, SReal mu, SReal for (c1=0; c10.01) + if (dim % 3) { - printf("\n WARNING dim should be dividable by 3 in nlcp_gaussseidel"); + dmsg_info("LCPcalc") << "dim should be dividable by 3 in nlcp_gaussseidelTimed" ; return 0; } + + const ctime_t t0 = CTime::getTime(); + const ctime_t tdiff = (ctime_t)(timeout*CTime::getTicksPerSec()); + // iterators int it,c1,i; @@ -1772,17 +1771,6 @@ int nlcp_gaussseidelTimed(int dim, SReal *dfree, SReal**W, SReal*f, SReal mu, SR W33 = (LocalBlock33 **) malloc (dim*sizeof(LocalBlock33)); for (c1=0; c1 sortedList; - listElem buf; - sortedList.clear(); - for (c1=0; c1vOp(params, vId.getId(ms), cparams->v().getId(ms), correctionId.getId(ms), velocityFactor); } - const double correctionFactor = cparams->constOrder() == sofa::core::ConstraintParams::ConstOrder::VEL ? velocityFactor : positionFactor; + const double correctionFactor = cparams->constOrder() == sofa::core::ConstraintOrder::VEL ? velocityFactor : positionFactor; //dx *= correctionFactor; ms->vOp(params,dxId.getId(ms),core::VecDerivId::null(), correctionId.getId(ms), correctionFactor); From 9653dc2e9e5573956b7b1e227df8c11d4268cbd0 Mon Sep 17 00:00:00 2001 From: Hugo Date: Fri, 20 Oct 2023 09:18:23 +0200 Subject: [PATCH 19/60] [all] Fix warnings (#4238) * [all] Fix warnings * fix warnings in SofaPhysicsSimulation * clean and fix compilation * fix compilation * fix SofaPhysicsSimulation.h * fix warning in caduceus scene due to missing Sofa.Component.LinearSystem module * fix SofaPhysicsSimulation.inl * use narrow_cast in ConstantSparsityPatternSystem --- .../lagrangian/solver/LCPConstraintSolver.cpp | 3 +- .../ConstantSparsityPatternSystem.inl | 9 ++---- .../mechanicalload/EllipsoidForceField.inl | 16 ++++++---- ...essedRowSparseMatrixConstraintEigenUtils.h | 2 +- .../CompressedRowSparseMatrixGeneric.h | 2 +- .../SofaPhysicsAPI/SofaPhysicsSimulation.cpp | 29 +++++++++---------- .../SofaPhysicsAPI/SofaPhysicsSimulation.h | 3 +- examples/Demos/caduceus.scn | 1 + 8 files changed, 33 insertions(+), 32 deletions(-) diff --git a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.cpp b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.cpp index 22f7f0437148..f2317f710a71 100644 --- a/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.cpp +++ b/Sofa/Component/Constraint/Lagrangian/Solver/src/sofa/component/constraint/lagrangian/solver/LCPConstraintSolver.cpp @@ -99,6 +99,7 @@ bool LCPConstraintSolver::prepareStates(const core::ConstraintParams * /*cParams msg_info() <<" propagate DXn performed - collision called" ; SCOPED_TIMER("resetContactForce"); + for (const auto& cc : l_constraintCorrections) { cc->resetContactForce(); @@ -1026,7 +1027,7 @@ int LCPConstraintSolver::lcp_gaussseidel_unbuilt(SReal *dfree, SReal *f, std::ve { bool elem1 = false; bool elem2 = false; - for (const auto cc : l_constraintCorrections) + for (const auto& cc : l_constraintCorrections) { if(cc->hasConstraintNumber(c1)) { diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.inl b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.inl index 565e95689b8e..7409254c279e 100644 --- a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.inl +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/ConstantSparsityPatternSystem.inl @@ -263,7 +263,8 @@ void ConstantSparsityPatternSystem::resizeSystem(sofa::Size n) if (this->getSystemMatrix()) { - if (n != this->getSystemMatrix()->rowSize() || n != this->getSystemMatrix()->colSize()) + Index nIndex = sofa::helper::narrow_cast(n); + if (nIndex != this->getSystemMatrix()->rowSize() || nIndex != this->getSystemMatrix()->colSize()) { this->getSystemMatrix()->resize(n, n); } @@ -336,12 +337,6 @@ void ConstantSparsityPatternSystem::preAssembleSystem(const co if (isConstantSparsityPatternUsedYet()) { - // this->getSystemMatrix()->compressed = true; - for (const auto& mat : this->m_localMappedMatrices) - { - // mat.second->compressed = true; - } - reinitLocalMatrices(this->template getLocalMatrixMap()); reinitLocalMatrices(this->template getLocalMatrixMap()); reinitLocalMatrices(this->template getLocalMatrixMap()); diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.inl b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.inl index c93af64a5895..4459517d8eb9 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.inl +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.inl @@ -104,11 +104,14 @@ void EllipsoidForceField::addForce(const sofa::core::MechanicalParams const Real stiffabs = helper::rabs(stiffness); //const Real s2 = (stiff < 0 ? - stiff*stiff : stiff*stiff ); Coord inv_r2; - for (int j=0; j* contacts = this->d_contacts.beginEdit(); contacts->clear(); f1.resize(p1.size()); - for (unsigned int i=0; i::addForce(const sofa::core::MechanicalParams Real norm = helper::rsqrt(norm2); Real v = norm-1; Coord grad; - for (int j=0; j::addForce(const sofa::core::MechanicalParams Real fact1 = -stiffabs / (norm * gnorm); Real fact2 = -stiffabs*v / gnorm; Real fact3 = -stiffabs*v / gnorm2; - for (int ci = 0; ci < N; ++ci) + for (unsigned int ci = 0; ci < N; ++ci) { - for (int cj = 0; cj < N; ++cj) + for (unsigned int cj = 0; cj < N; ++cj) c.m[ci][cj] = grad[ci]*grad[cj] * (fact1 + fact3*inv_r2[cj]); c.m[ci][ci] += fact2*inv_r2[ci]; } diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixConstraintEigenUtils.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixConstraintEigenUtils.h index 8627f1756666..dfdb2afd0c84 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixConstraintEigenUtils.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixConstraintEigenUtils.h @@ -203,7 +203,7 @@ void addMultTransposeEigen(LhsMatrixDeriv& lhs, const Eigen::SparseMatrixload(filename.c_str()); + m_RootNode = sofa::simulation::node::load(filename.c_str()); int result = API_SUCCESS; if (m_RootNode.get()) { sceneFileName = filename; - m_Simulation->init(m_RootNode.get()); + sofa::simulation::node::initRoot(m_RootNode.get()); result = updateOutputMeshes(); if ( useGUI ) { @@ -410,7 +409,7 @@ int SofaPhysicsSimulation::load(const char* cfilename) } else { - m_RootNode = m_Simulation->createNewGraph(""); + m_RootNode = sofa::simulation::getSimulation()->createNewGraph(""); return API_SCENE_FAILED; } initTexturesDone = false; @@ -425,7 +424,7 @@ int SofaPhysicsSimulation::unload() { if (m_RootNode.get()) { - m_Simulation->unload(m_RootNode); + sofa::simulation::node::unload(m_RootNode); } else { @@ -471,7 +470,7 @@ void SofaPhysicsSimulation::createScene() m_RootNode->setGravity({ 0,-9.8,0 }); this->createScene_impl(); - m_Simulation->init(m_RootNode.get()); + sofa::simulation::node::initRoot(m_RootNode.get()); updateOutputMeshes(); } @@ -604,7 +603,7 @@ void SofaPhysicsSimulation::reset() { if (getScene()) { - getSimulation()->reset(getScene()); + sofa::simulation::node::reset(getScene()); this->update(); } } @@ -632,8 +631,8 @@ void SofaPhysicsSimulation::step() sofa::simulation::Node* groot = getScene(); if (!groot) return; beginStep(); - getSimulation()->animate(groot); - getSimulation()->updateVisual(groot); + sofa::simulation::node::animate(groot); + sofa::simulation::node::updateVisual(groot); if ( useGUI ) { sofa::gui::common::BaseGUI* gui = sofa::gui::common::GUIManager::getGUI(); gui->stepMainLoop(); @@ -779,7 +778,7 @@ std::string SofaPhysicsSimulation::getMessage(int messageId, int& msgType) { const std::vector& msgs = m_msgHandler->getMessages(); - if (messageId >= msgs.size()) { + if (messageId >= (int)msgs.size()) { msgType = -1; return "Error messageId out of bounds"; } @@ -958,7 +957,7 @@ void SofaPhysicsSimulation::drawGL() if (!initTexturesDone) { std::cout << "INIT VISUAL" << std::endl; - getSimulation()->initTextures(groot); + sofa::simulation::node::initTextures(groot); bool setView = false; groot->get(currentCamera); if (!currentCamera) @@ -1049,7 +1048,7 @@ void SofaPhysicsSimulation::drawGL() glMatrixMode(GL_MODELVIEW); glLoadMatrixd(lastModelviewMatrix); - getSimulation()->draw(vparams,groot); + sofa::simulation::node::draw(vparams,groot); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); diff --git a/applications/projects/SofaPhysicsAPI/src/SofaPhysicsAPI/SofaPhysicsSimulation.h b/applications/projects/SofaPhysicsAPI/src/SofaPhysicsAPI/SofaPhysicsSimulation.h index 05446f685bc4..2f1418c702c9 100644 --- a/applications/projects/SofaPhysicsAPI/src/SofaPhysicsAPI/SofaPhysicsSimulation.h +++ b/applications/projects/SofaPhysicsAPI/src/SofaPhysicsAPI/SofaPhysicsSimulation.h @@ -115,7 +115,6 @@ class SOFA_SOFAPHYSICSAPI_API SofaPhysicsSimulation #endif protected: - sofa::simulation::Simulation* m_Simulation; sofa::simulation::Node::SPtr m_RootNode; std::string sceneFileName; /// Pointer to the LoggingMessageHandler @@ -174,7 +173,7 @@ class SOFA_SOFAPHYSICSAPI_API SofaPhysicsSimulation } sofa::simulation::Simulation* getSimulation() const { - return m_Simulation; + return sofa::simulation::getSimulation(); } sofa::simulation::Node* getScene() const { diff --git a/examples/Demos/caduceus.scn b/examples/Demos/caduceus.scn index 81eb50261f54..9843110f5034 100644 --- a/examples/Demos/caduceus.scn +++ b/examples/Demos/caduceus.scn @@ -21,6 +21,7 @@ + From ce3bf63c9611285d93d5dd0ea7b84e24a5b119d9 Mon Sep 17 00:00:00 2001 From: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Mon, 23 Oct 2023 03:21:24 +0200 Subject: [PATCH 20/60] [all] Add the folder sofa-launcher to the resources component (#4245) Add the folder sofa-launcher to the resources component Co-authored-by: Frederick Roy --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99b2d6cd2e68..eae67ddbbe39 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,11 +256,12 @@ install(FILES "${CMAKE_SOURCE_DIR}/CHANGELOG.md" DESTINATION . COMPONENT applica install(FILES "${CMAKE_SOURCE_DIR}/LICENSE.LGPL.txt" DESTINATION . COMPONENT applications) install(FILES "${CMAKE_SOURCE_DIR}/Authors.txt" DESTINATION . COMPONENT applications) -option(SOFA_INSTALL_RESOURCES_FILES "Copy resources files (etc/, share/, examples/) when installing" ON) +option(SOFA_INSTALL_RESOURCES_FILES "Copy resources files (etc/, share/, examples/, tools/sofa-launcher/) when installing" ON) ## Install resource files if(SOFA_INSTALL_RESOURCES_FILES) install(DIRECTORY share/ DESTINATION share/sofa COMPONENT resources) install(DIRECTORY examples/ DESTINATION share/sofa/examples COMPONENT resources) + install(DIRECTORY tools/sofa-launcher/ DESTINATION share/sofa/sofa-launcher COMPONENT resources) endif() file(WRITE "${CMAKE_BINARY_DIR}/plugins/README.txt" From 8f9cefacff6f469a2608d1b0c0ee8541e6ba2241 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Mon, 23 Oct 2023 04:26:34 +0200 Subject: [PATCH 21/60] [all] Remove TODO.md (#4244) The file does not seem to be used --- TODO.md | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 TODO.md diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 8a8a89b4bd8d..000000000000 --- a/TODO.md +++ /dev/null @@ -1,36 +0,0 @@ -TEMPLATE FOR THE CHANGE. - -message(STATUS "SofaBoundaryCondition:") -############################## COMPONENTS HERE ARE THE CORE SET ################################### - - -############################## COMPONENTS HERE ARE THE LIGHT-SET ################################### -if(SOFA_BUILD_COMPONENTSET_LIGHT) - list(APPEND HEADER_FILES - - ) - list(APPEND SOURCE_FILES - - ) -endif() - -############################## COMPONENTS HERE ARE THE STANDARD-SET ################################ -if(SOFA_BUILD_COMPONENTSET_STANDARD) - list(APPEND HEADER_FILES - - ) - list(APPEND SOURCE_FILES - - ) -endif() - -############################### COMPONENTS HERE ARE DEPRECATED #################################### -if(SOFA_BUILD_COMPONENTSET_FULL) - list(APPEND HEADER_FILES - - ) - list(APPEND SOURCE_FILES - - ) -endif() - From 54aba25b0e339f8a9988f6506fddf39826fbfd7b Mon Sep 17 00:00:00 2001 From: EulalieCoevoet Date: Mon, 23 Oct 2023 10:46:07 +0200 Subject: [PATCH 22/60] [MatrixAccumulator] adds 6x6 matrix handling (#4247) * [MatrixAccumulator] adds 6 6 matrix handling * [DerivativeMatrix] adds support of 6x6 matrices --------- Co-authored-by: Hugo --- Sofa/framework/Core/src/sofa/core/DerivativeMatrix.h | 2 ++ .../Core/src/sofa/core/MatrixAccumulator.cpp | 12 ++++++++++++ .../framework/Core/src/sofa/core/MatrixAccumulator.h | 2 ++ 3 files changed, 16 insertions(+) diff --git a/Sofa/framework/Core/src/sofa/core/DerivativeMatrix.h b/Sofa/framework/Core/src/sofa/core/DerivativeMatrix.h index f64172169c5b..eee2a173c9d6 100644 --- a/Sofa/framework/Core/src/sofa/core/DerivativeMatrix.h +++ b/Sofa/framework/Core/src/sofa/core/DerivativeMatrix.h @@ -50,6 +50,8 @@ class DerivativeMatrix : public MechanicalStatesMatrixAccumulators void operator+=(const sofa::type::Mat<2, 2, double>& value) const { mat->add(row, col, value); } void operator+=(const sofa::type::Mat<3, 3, float> & value) const { mat->add(row, col, value); } void operator+=(const sofa::type::Mat<3, 3, double>& value) const { mat->add(row, col, value); } + void operator+=(const sofa::type::Mat<6, 6, float> & value) const { mat->add(row, col, value); } + void operator+=(const sofa::type::Mat<6, 6, double>& value) const { mat->add(row, col, value); } [[nodiscard]] bool isValid() const { return mat != nullptr; } operator bool() const { return isValid(); } diff --git a/Sofa/framework/Core/src/sofa/core/MatrixAccumulator.cpp b/Sofa/framework/Core/src/sofa/core/MatrixAccumulator.cpp index 56f64a158165..0c8e7474a57d 100644 --- a/Sofa/framework/Core/src/sofa/core/MatrixAccumulator.cpp +++ b/Sofa/framework/Core/src/sofa/core/MatrixAccumulator.cpp @@ -60,6 +60,18 @@ void MatrixAccumulatorInterface::add(sofa::SignedIndex row, sofa::SignedIndex co matAdd(row, col, value); } +void MatrixAccumulatorInterface::add(sofa::SignedIndex row, sofa::SignedIndex col, + const sofa::type::Mat<6, 6, float>& value) +{ + matAdd(row, col, value); +} + +void MatrixAccumulatorInterface::add(sofa::SignedIndex row, sofa::SignedIndex col, + const sofa::type::Mat<6, 6, double>& value) +{ + matAdd(row, col, value); +} + helper::logging::MessageDispatcher::LoggerStream matrixaccumulator::RangeVerification:: logger() const { diff --git a/Sofa/framework/Core/src/sofa/core/MatrixAccumulator.h b/Sofa/framework/Core/src/sofa/core/MatrixAccumulator.h index 53bf7d77b751..0606bfdfd275 100644 --- a/Sofa/framework/Core/src/sofa/core/MatrixAccumulator.h +++ b/Sofa/framework/Core/src/sofa/core/MatrixAccumulator.h @@ -43,6 +43,8 @@ class SOFA_CORE_API MatrixAccumulatorInterface virtual void add(sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<2, 2, double>& value); virtual void add(sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, float> & value); virtual void add(sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, double>& value); + virtual void add(sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<6, 6, float> & value); + virtual void add(sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<6, 6, double>& value); virtual void clear() {} From ee0944331df889e2f932a188253c047a9eebbc3d Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Tue, 24 Oct 2023 03:58:54 +0200 Subject: [PATCH 23/60] [LinearAlgebra] Robustify accesses to empty matrices (#4236) * [LinearAlgebra] Robustify accesses to empty matrices Supersedes #4179 * Use isInvalid function --------- Co-authored-by: Hugo Co-authored-by: Frederick Roy --- .../CompressedRowSparseMatrixConstraint.h | 25 +++++++++++- .../CompressedRowSparseMatrixGeneric.h | 19 ++++++++- .../test/CompressedRowSparseMatrix_test.cpp | 39 +++++++++++++++++++ 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixConstraint.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixConstraint.h index f01c6043a95c..9f5fd8643d44 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixConstraint.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixConstraint.h @@ -74,6 +74,7 @@ class CompressedRowSparseMatrixConstraint : public sofa::linearalgebra::Compress using VecIndex = typename linearalgebra::CRSBlockTraits::VecIndex; using VecFlag = typename linearalgebra::CRSBlockTraits::VecFlag; using Index = typename VecIndex::value_type; + static constexpr Index s_invalidIndex = std::is_signed_v ? std::numeric_limits::lowest() : std::numeric_limits::max(); typedef typename CRSMatrix::Block Data; typedef typename CRSMatrix::Range Range; @@ -161,6 +162,11 @@ class CompressedRowSparseMatrixConstraint : public sofa::linearalgebra::Compress return m_internal; } + bool isInvalid() const + { + return m_internal == CompressedRowSparseMatrixConstraint::s_invalidIndex; + } + void operator++() // prefix { m_internal++; @@ -266,14 +272,27 @@ class CompressedRowSparseMatrixConstraint : public sofa::linearalgebra::Compress return m_internal; } + bool isInvalid() const + { + return m_internal == CompressedRowSparseMatrixConstraint::s_invalidIndex; + } + ColConstIterator begin() const { + if (isInvalid()) + { + return ColConstIterator(m_internal, s_invalidIndex, m_matrix); + } Range r = m_matrix->getRowRange(m_internal); return ColConstIterator(m_internal, r.begin(), m_matrix); } ColConstIterator end() const { + if (isInvalid()) + { + return ColConstIterator(m_internal, s_invalidIndex, m_matrix); + } Range r = m_matrix->getRowRange(m_internal); return ColConstIterator(m_internal, r.end(), m_matrix); } @@ -376,14 +395,16 @@ class CompressedRowSparseMatrixConstraint : public sofa::linearalgebra::Compress RowConstIterator begin() const { if constexpr (Policy::AutoCompress) const_cast(this)->compress(); /// \warning this violates the const-ness of the method ! - return RowConstIterator(this, 0); + return RowConstIterator(this, + this->rowIndex.empty() ? s_invalidIndex : 0); } /// Get the iterator corresponding to the end of the rows of blocks RowConstIterator end() const { if constexpr (Policy::AutoCompress) const_cast(this)->compress(); /// \warning this violates the const-ness of the method ! - return RowConstIterator(this, Index(this->rowIndex.size())); + return RowConstIterator(this, + this->rowIndex.empty() ? s_invalidIndex : Index(this->rowIndex.size())); } /// Get the iterator corresponding to the beginning of the rows of blocks diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixGeneric.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixGeneric.h index 26216ac517bf..4647c6f9a1a5 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixGeneric.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixGeneric.h @@ -116,6 +116,7 @@ class CompressedRowSparseMatrixGeneric : public TPolicy using VecIndex = typename CRSBlockTraits::VecIndex; using VecFlag = typename CRSBlockTraits::VecFlag; using Index = typename VecIndex::value_type; + static constexpr Index s_invalidIndex = std::is_signed_v ? std::numeric_limits::lowest() : std::numeric_limits::max(); typedef sofa::type::Vec DBlock; @@ -180,6 +181,10 @@ class CompressedRowSparseMatrixGeneric : public TPolicy typename VecIndex::const_iterator end (const VecIndex& b) const { return b.begin() + end (); } void operator++() { ++this->first; } void operator++(int) { ++this->first; } + bool isInvalid() const + { + return this->first == s_invalidIndex || this->second == s_invalidIndex; + } }; static bool sortedFind(const VecIndex& v, Range in, Index val, Index& result) @@ -211,7 +216,7 @@ public : VecIndex rowIndex; ///< indices of non-empty block rows VecIndex rowBegin; ///< column indices of non-empty blocks in each row. The column indices of the non-empty block within the i-th non-empty row are all the colsIndex[j], j in [rowBegin[i],rowBegin[i+1]) VecIndex colsIndex; ///< column indices of all the non-empty blocks, sorted by increasing row index and column index - VecBlock colsValue; ///< values of the non-empty blocks, in the same order as in colsIndex + VecBlock colsValue; ///< values of the non-empty blocks, in the same order as in colsIndex VecFlag touchedBlock; ///< boolean vector, i-th value is true if block has been touched since last compression. /// Additional storage to make block insertion more efficient @@ -254,7 +259,17 @@ public : const VecIndex& getRowIndex() const { return rowIndex; } const VecIndex& getRowBegin() const { return rowBegin; } - Range getRowRange(Index id) const { return Range(rowBegin[id], rowBegin[id+1]); } + + /// Returns the range of indices from the column indices corresponding to the id-th row + Range getRowRange(Index id) const + { + if (id + 1 >= rowBegin.size()) + { + return Range(s_invalidIndex, s_invalidIndex); + } + return Range(rowBegin[id], rowBegin[id+1]); + } + const VecIndex& getColsIndex() const { return colsIndex; } const VecBlock& getColsValue() const { return colsValue; } diff --git a/Sofa/framework/LinearAlgebra/test/CompressedRowSparseMatrix_test.cpp b/Sofa/framework/LinearAlgebra/test/CompressedRowSparseMatrix_test.cpp index 25c547681fdd..aa6fad1daefb 100644 --- a/Sofa/framework/LinearAlgebra/test/CompressedRowSparseMatrix_test.cpp +++ b/Sofa/framework/LinearAlgebra/test/CompressedRowSparseMatrix_test.cpp @@ -248,3 +248,42 @@ TEST(CompressedRowSparseMatrix, copyNonZeros) EXPECT_EQ(numberNonZeroValues1, numberNonZeroValues3); } + +TEST(CompressedRowSparseMatrix, emptyMatrixGetRowRange) +{ + EXPECT_EQ(sofa::linearalgebra::CompressedRowSparseMatrixMechanical::s_invalidIndex, std::numeric_limits::lowest()); + + const sofa::linearalgebra::CompressedRowSparseMatrixMechanical A; + + const auto range = A.getRowRange(0); + EXPECT_EQ(range.first, sofa::linearalgebra::CompressedRowSparseMatrixMechanical::s_invalidIndex); + EXPECT_EQ(range.second, sofa::linearalgebra::CompressedRowSparseMatrixMechanical::s_invalidIndex); +} + +TEST(CompressedRowSparseMatrixConstraint, emptyMatrixGetRowRange) +{ + EXPECT_EQ(sofa::linearalgebra::CompressedRowSparseMatrixConstraint::s_invalidIndex, std::numeric_limits::lowest()); + + const sofa::linearalgebra::CompressedRowSparseMatrixConstraint A; + + const auto begin = A.begin(); + EXPECT_EQ(begin.getInternal(), sofa::linearalgebra::CompressedRowSparseMatrixConstraint::s_invalidIndex); + + const auto end = A.end(); + EXPECT_EQ(end.getInternal(), sofa::linearalgebra::CompressedRowSparseMatrixConstraint::s_invalidIndex); + + EXPECT_EQ(begin, end); + + const auto checkIterator = [](const auto& iterator) + { + const auto itBegin = iterator.begin(); + const auto itEnd = iterator.end(); + + EXPECT_EQ(itBegin.getInternal(), sofa::linearalgebra::CompressedRowSparseMatrixConstraint::s_invalidIndex); + EXPECT_EQ(itEnd.getInternal(), sofa::linearalgebra::CompressedRowSparseMatrixConstraint::s_invalidIndex); + EXPECT_EQ(itBegin, itEnd); + }; + + checkIterator(begin); + checkIterator(end); +} From f670b1184f908a5c392f454b64621a130983c7ed Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 25 Oct 2023 11:12:49 +0200 Subject: [PATCH 24/60] [LinearAlgebra] Speedup accumulation on BTDMatrix (#4248) * [LinearAlgebra] Speedup accumulation on BTDMatrix * Fix --- .../src/sofa/linearalgebra/BTDMatrix.h | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BTDMatrix.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BTDMatrix.h index 9c8a852618e4..35910298f30b 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BTDMatrix.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BTDMatrix.h @@ -185,6 +185,12 @@ class BTDMatrix : public linearalgebra::BaseMatrix void add(Index i, Index j, double v) override; + /** + * Accumulation specialized on contributions of the same size than the blocks. + */ + template 3), int> = 0> + void add(Index row, Index col, const type::Mat& v); + void clear(Index i, Index j) override; void clearRow(Index i) override; @@ -226,6 +232,36 @@ class BTDMatrix : public linearalgebra::BaseMatrix } }; + +template +template 3), int>> +void BTDMatrix::add(Index row, Index col, + const type::Mat& v) +{ + if (row % BSIZE == 0 && col % BSIZE == 0) + { + const Index bi = row / BSIZE; + const Index bj = col / BSIZE; + const Index bindex = bj - bi + 1; + if (bindex >= 3) + { + return; + } + data[bi * 3 + bindex] += v; + } + else + { + for (sofa::Index i = 0; i < BSIZE; ++i) + { + for (sofa::Index j = 0; j < BSIZE; ++j) + { + this->add(row + i, col + j, v(i, j)); + } + } + } +} + + #if !defined(SOFA_LINEARALGEBRA_BTDMATRIX_CPP) extern template class SOFA_LINEARALGEBRA_API linearalgebra::BTDMatrix<6, SReal>; #endif From 3c2a1a1cef160a3dcd6035235d901c2af7bf3445 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 26 Oct 2023 07:15:38 +0200 Subject: [PATCH 25/60] [LinearAlgebra] Support 6x6 matrices accumulation in BaseMatrix (#4253) Since beams simulation is an important feature of SOFA --- .../AssemblingMatrixAccumulator.h | 16 +++ .../Core/src/sofa/core/MatrixAccumulator.h | 105 ++++++++---------- .../src/sofa/linearalgebra/BaseMatrix.cpp | 52 ++++++--- .../src/sofa/linearalgebra/BaseMatrix.h | 8 +- Sofa/framework/Type/src/sofa/type/fwd.h | 4 + 5 files changed, 107 insertions(+), 78 deletions(-) diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/AssemblingMatrixAccumulator.h b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/AssemblingMatrixAccumulator.h index 96b30d6eeaa7..7762619a7441 100644 --- a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/AssemblingMatrixAccumulator.h +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/AssemblingMatrixAccumulator.h @@ -76,6 +76,8 @@ class AssemblingMatrixAccumulator void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, double value) override; void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, float>& value) override; void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, double>& value) override; + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<6, 6, float>& value) override; + void add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<6, 6, double>& value) override; }; @@ -109,6 +111,20 @@ void AssemblingMatrixAccumulator::add(const core::matrixaccumulato value * static_cast(m_cachedFactor)); } template +void AssemblingMatrixAccumulator::add(const core::matrixaccumulator::no_check_policy&, const sofa::SignedIndex row, const sofa::SignedIndex col, const sofa::type::Mat<6, 6, float>& value) +{ + m_globalMatrix->add(row + m_cachedPositionInGlobalMatrix[0], + col + m_cachedPositionInGlobalMatrix[1], + value * static_cast(m_cachedFactor)); +} +template +void AssemblingMatrixAccumulator::add(const core::matrixaccumulator::no_check_policy&, const sofa::SignedIndex row, const sofa::SignedIndex col, const sofa::type::Mat<6, 6, double>& value) +{ + m_globalMatrix->add(row + m_cachedPositionInGlobalMatrix[0], + col + m_cachedPositionInGlobalMatrix[1], + value * static_cast(m_cachedFactor)); +} +template void AssemblingMatrixAccumulator::clear() {} diff --git a/Sofa/framework/Core/src/sofa/core/MatrixAccumulator.h b/Sofa/framework/Core/src/sofa/core/MatrixAccumulator.h index 0606bfdfd275..07c4bdcc13b3 100644 --- a/Sofa/framework/Core/src/sofa/core/MatrixAccumulator.h +++ b/Sofa/framework/Core/src/sofa/core/MatrixAccumulator.h @@ -125,82 +125,44 @@ class MatrixAccumulatorIndexChecker : public TBaseMatrixAccumulator [[maybe_unused]] std::shared_ptr indexVerificationStrategy; - void add(sofa::SignedIndex row, sofa::SignedIndex col, float value) override final + void add(const sofa::SignedIndex row, const sofa::SignedIndex col, const float value) override final { - if constexpr (TStrategy::verify_index::value) - { - if (indexVerificationStrategy) - { - indexVerificationStrategy->checkRowIndex(row); - indexVerificationStrategy->checkColIndex(col); - } - } - add(matrixaccumulator::no_check, row, col, value); + indexCheckedAdd(row, col, value); } - void add(sofa::SignedIndex row, sofa::SignedIndex col, double value) override final + void add(const sofa::SignedIndex row, const sofa::SignedIndex col, double value) override final { - if constexpr (TStrategy::verify_index::value) - { - if (indexVerificationStrategy) - { - indexVerificationStrategy->checkRowIndex(row); - indexVerificationStrategy->checkColIndex(col); - } - } - add(matrixaccumulator::no_check, row, col, value); + indexCheckedAdd(row, col, value); } - void add(sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<2, 2, float>& value) override final + void add(const sofa::SignedIndex row, const sofa::SignedIndex col, const sofa::type::Mat<2, 2, float>& value) override final { - if constexpr (TStrategy::verify_index::value) - { - if (indexVerificationStrategy) - { - indexVerificationStrategy->checkRowIndex(row); - indexVerificationStrategy->checkColIndex(col); - } - } - add(matrixaccumulator::no_check, row, col, value); + indexCheckedAdd(row, col, value); } - void add(sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<2, 2, double>& value) override final + void add(const sofa::SignedIndex row, const sofa::SignedIndex col, const sofa::type::Mat<2, 2, double>& value) override final { - if constexpr (TStrategy::verify_index::value) - { - if (indexVerificationStrategy) - { - indexVerificationStrategy->checkRowIndex(row); - indexVerificationStrategy->checkColIndex(col); - } - } - add(matrixaccumulator::no_check, row, col, value); + indexCheckedAdd(row, col, value); } - void add(sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, float>& value) override final + void add(const sofa::SignedIndex row, const sofa::SignedIndex col, const sofa::type::Mat<3, 3, float>& value) override final { - if constexpr (TStrategy::verify_index::value) - { - if (indexVerificationStrategy) - { - indexVerificationStrategy->checkRowIndex(row); - indexVerificationStrategy->checkColIndex(col); - } - } - add(matrixaccumulator::no_check, row, col, value); + indexCheckedAdd(row, col, value); } - void add(sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<3, 3, double>& value) override final + void add(const sofa::SignedIndex row, const sofa::SignedIndex col, const sofa::type::Mat<3, 3, double>& value) override final { - if constexpr (TStrategy::verify_index::value) - { - if (indexVerificationStrategy) - { - indexVerificationStrategy->checkRowIndex(row); - indexVerificationStrategy->checkColIndex(col); - } - } - add(matrixaccumulator::no_check, row, col, value); + indexCheckedAdd(row, col, value); + } + + void add(const sofa::SignedIndex row, const sofa::SignedIndex col, const sofa::type::Mat<6, 6, float>& value) override final + { + indexCheckedAdd(row, col, value); + } + + void add(const sofa::SignedIndex row, const sofa::SignedIndex col, const sofa::type::Mat<6, 6, double>& value) override final + { + indexCheckedAdd(row, col, value); } protected: @@ -232,6 +194,29 @@ class MatrixAccumulatorIndexChecker : public TBaseMatrixAccumulator { TBaseMatrixAccumulator::add(row, col, value); } + + virtual void add(const matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<6, 6, float>& value) + { + TBaseMatrixAccumulator::add(row, col, value); + } + virtual void add(const matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, const sofa::type::Mat<6, 6, double>& value) + { + TBaseMatrixAccumulator::add(row, col, value); + } + + template + void indexCheckedAdd(sofa::SignedIndex row, sofa::SignedIndex col, const T& value) + { + if constexpr (TStrategy::verify_index::value) + { + if (indexVerificationStrategy) + { + indexVerificationStrategy->checkRowIndex(row); + indexVerificationStrategy->checkColIndex(col); + } + } + add(matrixaccumulator::no_check, row, col, value); + } }; /** diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.cpp b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.cpp index 578afd4c72a3..be01bdfc3698 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.cpp +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.cpp @@ -106,32 +106,50 @@ struct BaseMatrixLinearOpMV_BlockDiagonal } }; +template +void matrixAdd(BaseMatrix* self, const Index row, const Index col, const sofa::type::Mat& M) +{ + for (unsigned int r = 0; r < L; ++r) + { + for (unsigned int c = 0; c < C; ++c) + { + self->add(row + r, col + c, M[r][c]); + } + } +} + ///Adding values from a 3x3d matrix this function may be overload to obtain better performances -void BaseMatrix::add(Index row, Index col, const type::Mat3x3d & _M) { - for (unsigned i=0;i<3;i++) - for (unsigned j=0;j<3;j++) - add(row + i, col + j, _M[i][j]); +void BaseMatrix::add(const Index row, const Index col, const type::Mat3x3d & _M) +{ + matrixAdd(this, row, col, _M); } ///Adding values from a 3x3f matrix this function may be overload to obtain better performances -void BaseMatrix::add(Index row, Index col, const type::Mat3x3f & _M) { - for (unsigned i=0;i<3;i++) - for (unsigned j=0;j<3;j++) - add(row + i, col + j, _M[i][j]); +void BaseMatrix::add(const Index row, const Index col, const type::Mat3x3f & _M) +{ + matrixAdd(this, row, col, _M); } ///Adding values from a 2x2d matrix this function may be overload to obtain better performances -void BaseMatrix::add(Index row, Index col, const type::Mat2x2d & _M) { - for (unsigned i=0;i<2;i++) - for (unsigned j=0;j<2;j++) - add(row + i, col + j, _M[i][j]); +void BaseMatrix::add(const Index row, const Index col, const type::Mat2x2d & _M) +{ + matrixAdd(this, row, col, _M); } ///Adding values from a 2x2f matrix this function may be overload to obtain better performances -void BaseMatrix::add(Index row, Index col, const type::Mat2x2f & _M) { - for (unsigned i=0;i<2;i++) - for (unsigned j=0;j<2;j++) - add(row + i, col + j, _M[i][j]); +void BaseMatrix::add(const Index row, const Index col, const type::Mat2x2f & _M) +{ + matrixAdd(this, row, col, _M); +} + +void BaseMatrix::add(const Index row, const Index col, const type::Mat6x6d& _M) +{ + matrixAdd(this, row, col, _M); +} + +void BaseMatrix::add(const Index row, const Index col, const type::Mat6x6f& _M) +{ + matrixAdd(this, row, col, _M); } @@ -839,4 +857,4 @@ std::istream& operator>>( std::istream& in, sofa::linearalgebra::BaseMatrix& m ) } -} // namespace sofa::linearalgebra \ No newline at end of file +} // namespace sofa::linearalgebra diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.h index 80d4d8a3420b..27f8d55b8293 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/BaseMatrix.h @@ -78,6 +78,12 @@ class SOFA_LINEARALGEBRA_API BaseMatrix ///Adding values from a 2x2f matrix. This function may be overload to obtain better performances virtual void add(Index row, Index col, const type::Mat2x2f & _M); + ///Adding values from a 6x6d matrix. This function may be overload to obtain better performances + virtual void add(Index row, Index col, const type::Mat6x6d & _M); + + ///Adding values from a 6x6f matrix. This function may be overload to obtain better performances + virtual void add(Index row, Index col, const type::Mat6x6f & _M); + /* /// Write the value of the element at row i, column j (using 0-based indices) virtual void set(Index i, Index j, float v) { set(i,j,(double)v); } /// Add v to the existing value of the element at row i, column j (using 0-based indices) @@ -1191,4 +1197,4 @@ SOFA_LINEARALGEBRA_API std::istream& operator>>( std::istream& in, sofa::lineara /// This line register the CompressedRowSparseMatrix to the messaging system /// this allow to write msg_info() instead of msg_info("CompressedRowSparseMatrix") /// which is nicer -MSG_REGISTER_CLASS(sofa::linearalgebra::BaseMatrix, "BaseMatrix") \ No newline at end of file +MSG_REGISTER_CLASS(sofa::linearalgebra::BaseMatrix, "BaseMatrix") diff --git a/Sofa/framework/Type/src/sofa/type/fwd.h b/Sofa/framework/Type/src/sofa/type/fwd.h index d8be17d9d8a7..56a61f5e8d6d 100644 --- a/Sofa/framework/Type/src/sofa/type/fwd.h +++ b/Sofa/framework/Type/src/sofa/type/fwd.h @@ -97,9 +97,13 @@ typedef Mat<3,4,double> Mat3x4d; typedef Mat<4,4,float> Mat4x4f; typedef Mat<4,4,double> Mat4x4d; +typedef Mat<6, 6, float> Mat6x6f; +typedef Mat<6, 6, double> Mat6x6d; + typedef Mat<2,2,SReal> Mat2x2; typedef Mat<3,3,SReal> Mat3x3; typedef Mat<4,4,SReal> Mat4x4; +typedef Mat<6,6,SReal> Mat6x6; typedef Mat<2,2,SReal> Matrix2; typedef Mat<3,3,SReal> Matrix3; From 6674feb585e50d8d1f5882e523bb17c0a0b98a62 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 26 Oct 2023 16:03:30 +0200 Subject: [PATCH 26/60] [LinearSolver] Implement parallel inverse product for all linear solvers (#4255) * [LinearSolver] Clean addJMInvJtLocal * small refactoring * Implement the parallel inverse product --- .../linearsolver/direct/SparseLDLSolver.h | 2 - .../linearsolver/direct/SparseLDLSolver.inl | 31 +--- .../iterative/MatrixLinearSolver.cpp | 9 + .../iterative/MatrixLinearSolver.h | 6 + .../iterative/MatrixLinearSolver.inl | 156 +++++++++++++++--- 5 files changed, 150 insertions(+), 54 deletions(-) diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.h index 44fb677240ea..0d2326367d68 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.h @@ -64,8 +64,6 @@ public : bool addJMInvJtLocal(TMatrix * M, ResMatrixType * result,const JMatrixType * J, SReal fact) override; int numStep; - Data d_parallelInverseProduct; - MatrixInvertData * createInvertData() override { return new InvertData(); } diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl index 17ae6e1f0e0f..66c852c015b2 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolver.inl @@ -41,34 +41,7 @@ namespace sofa::component::linearsolver::direct template SparseLDLSolver::SparseLDLSolver() : numStep(0) - , d_parallelInverseProduct(initData(&d_parallelInverseProduct, false, - "parallelInverseProduct", "Parallelize the computation of the product J*M^{-1}*J^T " - "where M is the matrix of the linear system and J is any " - "matrix with compatible dimensions")) -{ - this->addUpdateCallback("parallelODESolving", {&d_parallelInverseProduct}, - [this](const core::DataTracker& tracker) -> sofa::core::objectmodel::ComponentState - { - SOFA_UNUSED(tracker); - if (d_parallelInverseProduct.getValue()) - { - simulation::TaskScheduler* taskScheduler = simulation::MainTaskSchedulerFactory::createInRegistry(); - assert(taskScheduler); - - if (taskScheduler->getThreadCount() < 1) - { - taskScheduler->init(0); - msg_info() << "Task scheduler initialized on " << taskScheduler->getThreadCount() << " threads"; - } - else - { - msg_info() << "Task scheduler already initialized on " << taskScheduler->getThreadCount() << " threads"; - } - } - return this->d_componentState.getValue(); - }, - {}); -} +{} template void SparseLDLSolver::init() @@ -198,7 +171,7 @@ bool SparseLDLSolver::doAddJMInvJtLocal(ResMat const unsigned int JlocalRowSize = (unsigned int)Jlocal2global.size(); - const simulation::ForEachExecutionPolicy execution = d_parallelInverseProduct.getValue() ? + const simulation::ForEachExecutionPolicy execution = this->d_parallelInverseProduct.getValue() ? simulation::ForEachExecutionPolicy::PARALLEL : simulation::ForEachExecutionPolicy::SEQUENTIAL; diff --git a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.cpp b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.cpp index 21ff0c8347ee..0102405a53b2 100644 --- a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.cpp +++ b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.cpp @@ -115,6 +115,15 @@ void MatrixLinearSolver >(); } +template<> +bool MatrixLinearSolver::addJMInvJtLocal( + GraphScatteredMatrix* M, + MatrixLinearSolver::ResMatrixType* result, const + MatrixLinearSolver::JMatrixType* J, const SReal fact) +{ + return singleThreadAddJMInvJtLocal(M, result, J, fact); +} + // Force template instantiation using namespace sofa::linearalgebra; diff --git a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.h b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.h index d81f740c4424..79b7f86fa384 100644 --- a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.h +++ b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.h @@ -293,6 +293,10 @@ class MatrixLinearSolver : public BaseMatrixLinea void computeResidual(const core::ExecParams* params, linearalgebra::BaseVector* f) override; + ///< Parallelize the computation of the product J*M^{-1}*J^T where M is the + ///< matrix of the linear system and J is any matrix with compatible dimensions + Data d_parallelInverseProduct; + public: MatrixInvertData * getMatrixInvertData(linearalgebra::BaseMatrix * m); @@ -373,6 +377,8 @@ class MatrixLinearSolver : public BaseMatrixLinea SReal currentMFactor, currentBFactor, currentKFactor; + bool singleThreadAddJMInvJtLocal(Matrix * /*M*/,ResMatrixType * result,const JMatrixType * J, SReal fact); + protected: SingleLink< MatrixLinearSolver, diff --git a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.inl b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.inl index bd2690f4de64..e4e87e3b3557 100644 --- a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.inl +++ b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.inl @@ -49,7 +49,33 @@ MatrixLinearSolver::MatrixLinearSolver() , linearSystem() , currentMFactor(), currentBFactor(), currentKFactor() , l_linearSystem(initLink("linearSystem", "The linear system to solve")) + , d_parallelInverseProduct(initData(&d_parallelInverseProduct, false, + "parallelInverseProduct", "Parallelize the computation of the product J*M^{-1}*J^T " + "where M is the matrix of the linear system and J is any " + "matrix with compatible dimensions")) { + this->addUpdateCallback("parallelInverseProduct", {&d_parallelInverseProduct}, + [this](const core::DataTracker& tracker) -> sofa::core::objectmodel::ComponentState + { + SOFA_UNUSED(tracker); + if (d_parallelInverseProduct.getValue()) + { + simulation::TaskScheduler* taskScheduler = simulation::MainTaskSchedulerFactory::createInRegistry(); + assert(taskScheduler); + + if (taskScheduler->getThreadCount() < 1) + { + taskScheduler->init(0); + msg_info() << "Task scheduler initialized on " << taskScheduler->getThreadCount() << " threads"; + } + else + { + msg_info() << "Task scheduler already initialized on " << taskScheduler->getThreadCount() << " threads"; + } + } + return this->d_componentState.getValue(); + }, + {}); } template @@ -61,6 +87,8 @@ void MatrixLinearSolver::init() Inherit1::init(); checkLinearSystem(); + + this->d_componentState.setValue(core::objectmodel::ComponentState::Valid); } template @@ -374,41 +402,123 @@ void MatrixLinearSolver::invertSystem() } template -bool MatrixLinearSolver::addJMInvJtLocal(Matrix * /*M*/,ResMatrixType * result,const JMatrixType * J, SReal fact) +bool MatrixLinearSolver::addJMInvJtLocal(Matrix* M, ResMatrixType* result, const JMatrixType* J, const SReal fact) { - for (typename JMatrixType::Index row=0; rowrowSize(); row++) + if (!this->isComponentStateValid()) { - // STEP 1 : put each line of matrix Jt in the right hand term of the system - for (typename JMatrixType::Index i=0; icolSize(); i++) - { - getSystemRHVector()->set(i, J->element(row, i)); // linearSystem.systemMatrix->rowSize() - } + return true; + } - // STEP 2 : solve the system : - solveSystem(); + if (!d_parallelInverseProduct.getValue()) + { + return singleThreadAddJMInvJtLocal(M, result, J, fact); + } - // STEP 3 : project the result using matrix J - if (const linearalgebra::SparseMatrix * j = dynamic_cast * >(J)) // optimization for sparse matrix + static_assert(std::is_same_v>, "This function supposes a SparseMatrix"); + + auto* systemMatrix = getSystemMatrix(); + if (!systemMatrix) + { + msg_error() << "System matrix is not setup properly"; + return false; + } + + if (linearSystem.needInvert) + { + this->invert(*systemMatrix); + linearSystem.needInvert = false; + } + + simulation::TaskScheduler* taskScheduler = simulation::MainTaskSchedulerFactory::createInRegistry(); + assert(taskScheduler); + + sofa::type::vector rhsVector(J->rowSize()); + sofa::type::vector lhsVector(J->rowSize()); + sofa::type::vector columnResult(J->rowSize()); + + std::mutex mutex; + + simulation::parallelForEach(*taskScheduler, 0, J->rowSize(), + [&](const typename JMatrixType::Index row) { - const typename linearalgebra::SparseMatrix::LineConstIterator jitend = j->end(); - for (typename linearalgebra::SparseMatrix::LineConstIterator jit = j->begin(); jit != jitend; ++jit) + rhsVector[row].resize(J->colSize()); + lhsVector[row].resize(J->colSize()); + columnResult[row].resize(J->colSize()); + + // STEP 1 : put each line of matrix Jt in the right hand term of the system + for (typename JMatrixType::Index i = 0; i < J->colSize(); ++i) + { + rhsVector[row].set(i, J->element(row, i)); + } + + // STEP 2 : solve the system : + this->solve(*systemMatrix, lhsVector[row], rhsVector[row]); + + // STEP 3 : project the result using matrix J + for (const auto& [row2, line] : *J) { - auto row2 = jit->first; - double acc = 0.0; - for (typename linearalgebra::SparseMatrix::LElementConstIterator i2 = jit->second.begin(), i2end = jit->second.end(); i2 != i2end; ++i2) + Real acc = 0; + for (const auto& [col2, val2] : line) { - auto col2 = i2->first; - double val2 = i2->second; - acc += val2 * getSystemLHVector()->element(col2); + acc += val2 * lhsVector[row].element(col2); } acc *= fact; - result->add(row2,row,acc); + columnResult[row][row2] += acc; + } + + // STEP 4 : assembly of the result + std::lock_guard lock(mutex); + + for (const auto& [row2, line] : *J) + { + result->add(row2, row, columnResult[row][row2]); } } - else + ); + + return true; +} + +template +bool MatrixLinearSolver::singleThreadAddJMInvJtLocal(Matrix* M, ResMatrixType* result, const JMatrixType* J, const SReal fact) +{ + SOFA_UNUSED(M); + static_assert(std::is_same_v>, "This function supposes a SparseMatrix"); + + auto* systemMatrix = getSystemMatrix(); + if (!systemMatrix) + { + msg_error() << "System matrix is not setup properly"; + return false; + } + + if (linearSystem.needInvert) + { + this->invert(*systemMatrix); + linearSystem.needInvert = false; + } + + for (typename JMatrixType::Index row = 0; row < J->rowSize(); ++row) + { + // STEP 1 : put each line of matrix Jt in the right hand term of the system + for (typename JMatrixType::Index i = 0; i < J->colSize(); ++i) { - dmsg_error() << "addJMInvJt is only implemented for linearalgebra::SparseMatrix" ; - return false; + this->getSystemRHVector()->set(i, J->element(row, i)); // linearSystem.systemMatrix->rowSize() + } + + // STEP 2 : solve the system : + this->solve(*systemMatrix, *this->getSystemLHVector(), *this->getSystemRHVector()); + + // STEP 3 : project the result using matrix J + for (const auto& [row2, line] : *J) + { + Real acc = 0; + for (const auto& [col2, val2] : line) + { + acc += val2 * getSystemLHVector()->element(col2); + } + acc *= fact; + result->add(row2, row, acc); } } From 6568b02051bc99929249a99491c7af73b2330158 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Fri, 27 Oct 2023 17:45:44 +0900 Subject: [PATCH 27/60] [GL] Remove deprecated (and incomplete) Color class (#4264) remove gl::Color, deprecated for a long time --- Sofa/GL/CMakeLists.txt | 1 - Sofa/GL/src/sofa/gl/Color.cpp | 57 ----------------------------------- Sofa/GL/src/sofa/gl/Color.h | 23 ++------------ 3 files changed, 2 insertions(+), 79 deletions(-) delete mode 100644 Sofa/GL/src/sofa/gl/Color.cpp diff --git a/Sofa/GL/CMakeLists.txt b/Sofa/GL/CMakeLists.txt index d0b2ae5ea785..c0d94be07f52 100644 --- a/Sofa/GL/CMakeLists.txt +++ b/Sofa/GL/CMakeLists.txt @@ -39,7 +39,6 @@ set(SOURCE_FILES ${SOFAGLSRC_ROOT}/Capture.cpp ${SOFAGLSRC_ROOT}/Texture.cpp ${SOFAGLSRC_ROOT}/VideoRecorderFFMPEG.cpp - ${SOFAGLSRC_ROOT}/Color.cpp ${SOFAGLSRC_ROOT}/gl.cpp ${SOFAGLSRC_ROOT}/TransformationGL.cpp ${SOFAGLSRC_ROOT}/DrawToolGL.cpp diff --git a/Sofa/GL/src/sofa/gl/Color.cpp b/Sofa/GL/src/sofa/gl/Color.cpp deleted file mode 100644 index 9a46e2943b65..000000000000 --- a/Sofa/GL/src/sofa/gl/Color.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/****************************************************************************** -* SOFA, Simulation Open-Framework Architecture * -* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU Lesser General Public License as published by * -* the Free Software Foundation; either version 2.1 of the License, or (at * -* your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but WITHOUT * -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * -* for more details. * -* * -* You should have received a copy of the GNU Lesser General Public License * -* along with this program. If not, see . * -******************************************************************************* -* Authors: The SOFA Team and external contributors (see Authors.txt) * -* * -* Contact information: contact@sofa-framework.org * -******************************************************************************/ -#include -#include -#include -#include -#include - -namespace sofa::gl -{ -using sofa::type::RGBAColor ; - -void Color::setHSVA( float h, float s, float v, float a ) -{ - msg_deprecated("gl::Color") << "The setHSVA function is deprecated. " - "Using deprecated function may result in incorrect behavior as well as loss of performance" - "To remove this error message you can update the setHSVA function with the following: " - "Color::set( RGBAColor::fromHSVA(h,s,v,a) ); " ; - - glColor4fv( RGBAColor::fromHSVA(h,s,v,a).data() ); -} - -void Color::getHSVA( float* rgba, float h, float s, float v, float a ) -{ - assert(rgba!=nullptr) ; - - msg_deprecated("gl::Color") << "The getHSVA function is deprecated. " - "Using deprecated function may result in incorrect behavior as well as loss of performance" - "To remove this error message you can update the getHSVA function with the following: " - "RGBAColor::fromHSVA(h,s,v,a).data() " ; - RGBAColor tmp=RGBAColor::fromHSVA(h,s,v,a); - for(unsigned int i=0; i<4;i++){ - rgba[i] = tmp[i] ; - } -} - - -} // namespace sofa::gl diff --git a/Sofa/GL/src/sofa/gl/Color.h b/Sofa/GL/src/sofa/gl/Color.h index 951ce023ff69..59ed481fd880 100644 --- a/Sofa/GL/src/sofa/gl/Color.h +++ b/Sofa/GL/src/sofa/gl/Color.h @@ -20,25 +20,6 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include +#include -#include - -/// Forward declaration -namespace sofa::gl -{ - -class SOFA_GL_API Color -{ -public: - static void set(const sofa::type::RGBAColor& color) ; - - static void setHSVA( float h, float s, float v, float a ); - static void getHSVA( float* rgba, float h, float s, float v, float a ); - -private: - Color(); - ~Color(); -}; - -} // namespace sofa::gl +SOFA_DISABLED_HEADER_NOT_REPLACED("v17.06", "v23.12") From 1abed066d54f0ca2976dcaf1ef435fdb017af8b1 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Mon, 30 Oct 2023 05:13:45 +0100 Subject: [PATCH 28/60] [example] Speedup TorusFall with parallel inverse product (#4256) --- examples/Benchmark/Performance/TorusFall.scn | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/Benchmark/Performance/TorusFall.scn b/examples/Benchmark/Performance/TorusFall.scn index 5833f1fa044e..8c1082f18e02 100644 --- a/examples/Benchmark/Performance/TorusFall.scn +++ b/examples/Benchmark/Performance/TorusFall.scn @@ -30,7 +30,7 @@ - + @@ -49,7 +49,7 @@ - + @@ -71,7 +71,7 @@ - + @@ -93,7 +93,7 @@ - + @@ -115,7 +115,7 @@ - + @@ -137,7 +137,7 @@ - + @@ -159,7 +159,7 @@ - + @@ -181,7 +181,7 @@ - + @@ -203,7 +203,7 @@ - + @@ -225,7 +225,7 @@ - + @@ -247,7 +247,7 @@ - + From 92445a053db662d7b84cbf1704ba5cd3b70c3b65 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Thu, 2 Nov 2023 18:33:43 +0900 Subject: [PATCH 29/60] [FEM, Mapping] dont mix type::fixed_array and type::Vec (#4269) use same type as the definition --- .../component/mapping/linear/BarycentricMappingRigid.cpp | 2 +- .../solidmechanics/fem/elastic/HexahedronFEMForceField.inl | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.cpp b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.cpp index 212bd8a786f6..35911c33c3c2 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.cpp +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/BarycentricMappingRigid.cpp @@ -86,7 +86,7 @@ void BarycentricMapperHexahedronSetTopology coefs; defaulttype::Vec3Types::Coord pos; pos[0] = mapData[j].baryCoords[0]; pos[1] = mapData[j].baryCoords[1]; diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl index 8cf1fb7787ec..63546fe20621 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/HexahedronFEMForceField.inl @@ -767,7 +767,7 @@ void HexahedronFEMForceField::accumulateForceSmall ( WDataRefVecDeriv nodes[w] = p[elem[w]]; // positions of the deformed and displaced Tetrahedron in its frame - Vec<8,Coord> deformed; + sofa::type::fixed_array deformed; for(int w=0; w<8; ++w) deformed[w] = nodes[w]; @@ -869,7 +869,7 @@ void HexahedronFEMForceField::accumulateForceLarge( WDataRefVecDeriv computeRotationLarge( _rotations[i], horizontal,vertical); // positions of the deformed and displaced Tetrahedron in its frame - type::Vec<8,Coord> deformed; + sofa::type::fixed_array deformed; for(int w=0; w<8; ++w) deformed[w] = _rotations[i] * nodes[w]; @@ -1063,7 +1063,7 @@ void HexahedronFEMForceField::accumulateForcePolar( WDataRefVecDeriv computeRotationPolar( _rotations[i], nodes ); // positions of the deformed and displaced Tetrahedre in its frame - type::Vec<8,Coord> deformed; + sofa::type::fixed_array deformed; for(int j=0; j<8; ++j) deformed[j] = _rotations[i] * nodes[j]; From ddfe19535200c19637f96ace845b04317ca4feee Mon Sep 17 00:00:00 2001 From: Olivier Roussel Date: Thu, 2 Nov 2023 11:43:01 +0100 Subject: [PATCH 30/60] [all] Fix headeronly extlibs licenses (#4272) * add missing license file for nlohmann json. * homogenize license files names. --- extlibs/difflib/{LICENCE => LICENSE.MIT} | 0 extlibs/json/LICENSE.MIT | 21 +++++++++++++++++++++ extlibs/stb/{LICENCE => LICENSE.MIT} | 0 3 files changed, 21 insertions(+) rename extlibs/difflib/{LICENCE => LICENSE.MIT} (100%) create mode 100644 extlibs/json/LICENSE.MIT rename extlibs/stb/{LICENCE => LICENSE.MIT} (100%) diff --git a/extlibs/difflib/LICENCE b/extlibs/difflib/LICENSE.MIT similarity index 100% rename from extlibs/difflib/LICENCE rename to extlibs/difflib/LICENSE.MIT diff --git a/extlibs/json/LICENSE.MIT b/extlibs/json/LICENSE.MIT new file mode 100644 index 000000000000..1c1f7a690d81 --- /dev/null +++ b/extlibs/json/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013-2022 Niels Lohmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/extlibs/stb/LICENCE b/extlibs/stb/LICENSE.MIT similarity index 100% rename from extlibs/stb/LICENCE rename to extlibs/stb/LICENSE.MIT From 14bfbd3087211a3c599033655a1b721c09cf1421 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Fri, 3 Nov 2023 22:55:16 +0900 Subject: [PATCH 31/60] [Type, Helper] Remove unused __STL_MEMBER_TEMPLATES parts (#4251) remove sgi stl member template macro Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Co-authored-by: erik pernod --- Sofa/framework/Helper/src/sofa/helper/integer_id.h | 6 ------ .../Helper/src/sofa/helper/map_ptr_stable_compare.h | 9 --------- Sofa/framework/Type/src/sofa/type/SVector.h | 7 ------- Sofa/framework/Type/src/sofa/type/vector_T.h | 6 ------ 4 files changed, 28 deletions(-) diff --git a/Sofa/framework/Helper/src/sofa/helper/integer_id.h b/Sofa/framework/Helper/src/sofa/helper/integer_id.h index e8457a2bd946..929f15e15f22 100644 --- a/Sofa/framework/Helper/src/sofa/helper/integer_id.h +++ b/Sofa/framework/Helper/src/sofa/helper/integer_id.h @@ -251,14 +251,8 @@ class vector_id : public vector /// Constructor vector_id(const std::vector& x): Inherit(x) {} -#ifdef __STL_MEMBER_TEMPLATES - /// Constructor - template - vector_id(InputIterator first, InputIterator last): Inherit(first,last) {} -#else /* __STL_MEMBER_TEMPLATES */ /// Constructor vector_id(const_iterator first, const_iterator last): Inherit(first,last) {} -#endif /* __STL_MEMBER_TEMPLATES */ /// Read/write random access, with explicit Index reference at(Index n) diff --git a/Sofa/framework/Helper/src/sofa/helper/map_ptr_stable_compare.h b/Sofa/framework/Helper/src/sofa/helper/map_ptr_stable_compare.h index 5d4cb2fa48eb..df46829197b5 100644 --- a/Sofa/framework/Helper/src/sofa/helper/map_ptr_stable_compare.h +++ b/Sofa/framework/Helper/src/sofa/helper/map_ptr_stable_compare.h @@ -158,20 +158,11 @@ class map_ptr_stable_compare : public std::map { } -#ifdef __STL_MEMBER_TEMPLATES - /// Constructor - template - map_ptr_stable_compare(InputIterator first, InputIterator last) - :Inherit(first,last, key_compare(new stable_id_map_type())) - ,m_stable_id_map(Inherit::key_comp().get_stable_id_map()) - {} -#else /* __STL_MEMBER_TEMPLATES */ /// Constructor map_ptr_stable_compare(const_iterator first, const_iterator last) :Inherit(first,last, key_compare(new stable_id_map_type()) ) ,m_stable_id_map(Inherit::key_comp().get_stable_id_map()) {} -#endif /* __STL_MEMBER_TEMPLATES */ private: /// smart ptr for memory ownership diff --git a/Sofa/framework/Type/src/sofa/type/SVector.h b/Sofa/framework/Type/src/sofa/type/SVector.h index b321ea64c0d5..cd002a7b8259 100644 --- a/Sofa/framework/Type/src/sofa/type/SVector.h +++ b/Sofa/framework/Type/src/sofa/type/SVector.h @@ -72,15 +72,8 @@ class SVector: public type::vector > return *this; } -#ifdef __STL_MEMBER_TEMPLATES - /// Constructor - template - SVector(InputIterator first, InputIterator last): Inherit(first,last) {} -#else /* __STL_MEMBER_TEMPLATES */ /// Constructor SVector(typename SVector::const_iterator first, typename SVector::const_iterator last): Inherit(first,last) {} -#endif /* __STL_MEMBER_TEMPLATES */ - std::ostream& write ( std::ostream& os ) const { diff --git a/Sofa/framework/Type/src/sofa/type/vector_T.h b/Sofa/framework/Type/src/sofa/type/vector_T.h index c24edc4471b1..182930ffe408 100644 --- a/Sofa/framework/Type/src/sofa/type/vector_T.h +++ b/Sofa/framework/Type/src/sofa/type/vector_T.h @@ -93,14 +93,8 @@ class vector : public std::vector > return *this; } -#ifdef __STL_MEMBER_TEMPLATES - /// Constructor - template - vector(InputIterator first, InputIterator last): std::vector(first,last) {} -#else /* __STL_MEMBER_TEMPLATES */ /// Constructor vector(typename vector::const_iterator first, typename vector::const_iterator last): std::vector(first,last) {} -#endif /* __STL_MEMBER_TEMPLATES */ /// Read/write random access reference operator[](Size n) From 4c33540b608539c280ffc006c3de4cb737d6071b Mon Sep 17 00:00:00 2001 From: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:14:08 +0100 Subject: [PATCH 32/60] [Helper] ADD option to cmake for advanced timer (#4259) * ADD SOFA_SCOPED_ADVANCED_TIMER option to cmake that activate the use of the classical advanced timers * Modify macro name and fix compilation error --------- Co-authored-by: erik pernod --- Sofa/framework/Config/CMakeLists.txt | 8 +++++++- Sofa/framework/Config/src/sofa/config.h.in | 1 + .../src/sofa/helper/ScopedAdvancedTimer.h | 19 +++++++++++++++---- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Sofa/framework/Config/CMakeLists.txt b/Sofa/framework/Config/CMakeLists.txt index caa56c984d1f..2e58f601a782 100644 --- a/Sofa/framework/Config/CMakeLists.txt +++ b/Sofa/framework/Config/CMakeLists.txt @@ -242,7 +242,7 @@ if(SOFA_OPENMP) endif() ## Tracy -option(SOFA_TRACY "Compile SOFA with the Tracy profiler client") +option(SOFA_TRACY "Compile SOFA with the Tracy profiler client" OFF) if (SOFA_TRACY) set(SOFA_TRACY_VERSION v0.9.1) include(FetchContent) @@ -259,6 +259,12 @@ if (SOFA_TRACY) message(STATUS "SOFA is compiled with the Tracy profiler client. Use the Tracy server ${SOFA_TRACY_VERSION}.") endif() + +option(SOFA_ENABLE_BUILTIN_TIMER "Enable the builtin timers" ON) +if(SOFA_ENABLE_BUILTIN_TIMER) + set(SOFA_ENABLE_SCOPED_ADVANCED_TIMER 1) +endif() + # An important C++11 feature may be not enabled due to # the compiler being built without the --enable-libstdcxx-time option. if(CMAKE_COMPILER_IS_GNUCXX) diff --git a/Sofa/framework/Config/src/sofa/config.h.in b/Sofa/framework/Config/src/sofa/config.h.in index 66fc7c1ff4ae..ac3c4546f352 100644 --- a/Sofa/framework/Config/src/sofa/config.h.in +++ b/Sofa/framework/Config/src/sofa/config.h.in @@ -40,6 +40,7 @@ #cmakedefine SOFA_WITH_DOUBLE #cmakedefine SOFA_WITH_DEVTOOLS +#cmakedefine SOFA_ENABLE_SCOPED_ADVANCED_TIMER #ifdef WIN32 #define UNICODE diff --git a/Sofa/framework/Helper/src/sofa/helper/ScopedAdvancedTimer.h b/Sofa/framework/Helper/src/sofa/helper/ScopedAdvancedTimer.h index f324492aad1e..4a9c6ad434dc 100644 --- a/Sofa/framework/Helper/src/sofa/helper/ScopedAdvancedTimer.h +++ b/Sofa/framework/Helper/src/sofa/helper/ScopedAdvancedTimer.h @@ -65,9 +65,20 @@ ScopedAdvancedTimer::ScopedAdvancedTimer(const char* message, T* obj) #ifdef TRACY_ENABLE #include - #define SCOPED_TIMER(name) ZoneScopedN(name) - #define SCOPED_TIMER_VARNAME(varname, name) ZoneNamedN(varname, name, true) + #define SCOPED_TIMER_TR(name) ZoneScopedN(name) + #define SCOPED_TIMER_VARNAME_TR(varname, name) ZoneNamedN(varname##_tr, name, true) #else - #define SCOPED_TIMER(name) sofa::helper::ScopedAdvancedTimer sofaScopedTimer(name) - #define SCOPED_TIMER_VARNAME(varname, name) sofa::helper::ScopedAdvancedTimer varname(name) + #define SCOPED_TIMER_TR(name) + #define SCOPED_TIMER_VARNAME_TR(varname, name) #endif + +#ifdef SOFA_ENABLE_SCOPED_ADVANCED_TIMER + #define SCOPED_TIMER_AD(name) sofa::helper::ScopedAdvancedTimer sofaScopedTimer(name) + #define SCOPED_TIMER_VARNAME_AD(varname, name) sofa::helper::ScopedAdvancedTimer varname##_ad(name) +#else + #define SCOPED_TIMER_AD(name) + #define SCOPED_TIMER_VARNAME_AD(varname, name) +#endif + +#define SCOPED_TIMER(name) SCOPED_TIMER_TR(name); SCOPED_TIMER_AD(name) +#define SCOPED_TIMER_VARNAME(varname, name) SCOPED_TIMER_VARNAME_TR(varname, name); SCOPED_TIMER_VARNAME_AD(varname, name) \ No newline at end of file From 4e96aba1040a418ee8060d527b7f784b2abd5425 Mon Sep 17 00:00:00 2001 From: Hugo Date: Fri, 3 Nov 2023 22:40:40 +0100 Subject: [PATCH 33/60] [github] Fix name of PR author in GitHub workflows (#4267) Co-authored-by: erik pernod --- .github/workflows/label-checker.yml | 2 +- .github/workflows/pr-title-checker.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/label-checker.yml b/.github/workflows/label-checker.yml index 8c015e4dd1b1..966efef6e694 100644 --- a/.github/workflows/label-checker.yml +++ b/.github/workflows/label-checker.yml @@ -48,7 +48,7 @@ jobs: // If no descriptive label is set, add a comment in the PR and make the action check fail if (!hasDescriptiveLabel) { - const comment = ':warning: :warning: :warning:
@' + context.repo.owner + ' your PR does not include any **descriptive** label :label:
Make sure to add an appropriate [PR label](https://github.com/sofa-framework/sofa/labels) before merge.
:warning: :warning: :warning:'; + const comment = ':warning: :warning: :warning:
@' + context.payload.pull_request.user.login + ' your PR does not include any **descriptive** label :label:
Make sure to add an appropriate [PR label](https://github.com/sofa-framework/sofa/labels) before merge.
:warning: :warning: :warning:'; github.issues.createComment({ issue_number: prNumber, owner: context.repo.owner, diff --git a/.github/workflows/pr-title-checker.yml b/.github/workflows/pr-title-checker.yml index 4dd4bd287a4c..4a07fc661b99 100644 --- a/.github/workflows/pr-title-checker.yml +++ b/.github/workflows/pr-title-checker.yml @@ -39,7 +39,7 @@ jobs: // Add comment in the PR to warn the author if (!valid) { - const comment = ':warning: :warning: :warning:
@'+context.repo.owner+' your PR title is not following the required format :pencil2:
'+commentExplain+':warning: :warning: :warning:'; + const comment = ':warning: :warning: :warning:
@' + context.payload.pull_request.user.login + ' your PR title is not following the required format :pencil2:
'+commentExplain+':warning: :warning: :warning:'; github.issues.createComment({ issue_number: prNumber, owner: context.repo.owner, From 3b405671c429caa48dfba47804535f1c8d164aae Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Sat, 4 Nov 2023 07:12:39 +0900 Subject: [PATCH 34/60] [Topology.Mapping] SimpleTesselatedHexaTopologicalMapping: use correct type for Index (#4279) fix index type Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Co-authored-by: erik pernod --- ...SimpleTesselatedHexaTopologicalMapping.cpp | 173 +++++++++--------- .../SimpleTesselatedHexaTopologicalMapping.h | 8 +- 2 files changed, 89 insertions(+), 92 deletions(-) diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SimpleTesselatedHexaTopologicalMapping.cpp b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SimpleTesselatedHexaTopologicalMapping.cpp index a230355de224..1fcdd4c38a5f 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SimpleTesselatedHexaTopologicalMapping.cpp +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SimpleTesselatedHexaTopologicalMapping.cpp @@ -39,7 +39,6 @@ using namespace sofa::type; using namespace sofa::defaulttype; using namespace sofa::component::mapping::linear; using namespace sofa::core::topology; -using sofa::type::fixed_array; // Register in the Factory int SimpleTesselatedHexaTopologicalMappingClass = core::RegisterObject ( "Special case of mapping where HexahedronSetTopology is converted into a finer HexahedronSetTopology" ) @@ -72,7 +71,7 @@ void SimpleTesselatedHexaTopologicalMapping::init() toModel->addPoint(fromModel->getPX(i), fromModel->getPY(i), fromModel->getPZ(i)); } - size_t pointIndex = pointMappedFromPoint.size(); + sofa::Index pointIndex = static_cast(pointMappedFromPoint.size()); Vec3 p; for (std::size_t i=0; igetNbHexahedra(); ++i) @@ -89,97 +88,96 @@ void SimpleTesselatedHexaTopologicalMapping::init() Vec3 p7(fromModel->getPX(h[7]), fromModel->getPY(h[7]), fromModel->getPZ(h[7])); // points mapped from edges - std::pair, int>::iterator, bool> insert_result; - insert_result = pointMappedFromEdge.insert(std::make_pair(fixed_array(h[0],h[1]),pointIndex)); - if(insert_result.second) + bool insertResultSuccessful = pointMappedFromEdge.insert({ {h[0],h[1]},pointIndex }).second; + if(insertResultSuccessful) { p = (p0+p1)/2; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_result = pointMappedFromEdge.insert(std::make_pair(fixed_array(h[1],h[(2)]),pointIndex)); - if(insert_result.second) + insertResultSuccessful = pointMappedFromEdge.insert({{h[1],h[(2)]},pointIndex }).second; + if(insertResultSuccessful) { p = (p1+p2)/2; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_result = pointMappedFromEdge.insert(std::make_pair(fixed_array(h[3],h[2]),pointIndex)); - if(insert_result.second) + insertResultSuccessful = pointMappedFromEdge.insert({{h[3],h[2]},pointIndex }).second; + if(insertResultSuccessful) { p = (p3+p2)/2; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_result = pointMappedFromEdge.insert(std::make_pair(fixed_array(h[0],h[3]),pointIndex)); - if(insert_result.second) + insertResultSuccessful = pointMappedFromEdge.insert({{h[0],h[3]},pointIndex }).second; + if(insertResultSuccessful) { p = (p0+p3)/2; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_result = pointMappedFromEdge.insert(std::make_pair(fixed_array(h[0],h[4]),pointIndex)); - if(insert_result.second) + insertResultSuccessful = pointMappedFromEdge.insert({{h[0],h[4]},pointIndex }).second; + if(insertResultSuccessful) { p = (p0+p4)/2; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_result = pointMappedFromEdge.insert(std::make_pair(fixed_array(h[1],h[5]),pointIndex)); - if(insert_result.second) + insertResultSuccessful = pointMappedFromEdge.insert({{h[1],h[5]},pointIndex }).second; + if(insertResultSuccessful) { p = (p1+p5)/2; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_result = pointMappedFromEdge.insert(std::make_pair(fixed_array(h[2],h[6]),pointIndex)); - if(insert_result.second) + insertResultSuccessful = pointMappedFromEdge.insert({{h[2],h[6]},pointIndex }).second; + if(insertResultSuccessful) { p = (p2+p6)/2; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_result = pointMappedFromEdge.insert(std::make_pair(fixed_array(h[3],h[7]),pointIndex)); - if(insert_result.second) + insertResultSuccessful = pointMappedFromEdge.insert({{h[3],h[7]},pointIndex }).second; + if(insertResultSuccessful) { p = (p3+p7)/2; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_result = pointMappedFromEdge.insert(std::make_pair(fixed_array(h[4],h[5]),pointIndex)); - if(insert_result.second) + insertResultSuccessful = pointMappedFromEdge.insert({{h[4],h[5]},pointIndex }).second; + if(insertResultSuccessful) { p = (p4+p5)/2; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_result = pointMappedFromEdge.insert(std::make_pair(fixed_array(h[5],h[6]),pointIndex)); - if(insert_result.second) + insertResultSuccessful = pointMappedFromEdge.insert({{h[5],h[6]},pointIndex }).second; + if(insertResultSuccessful) { p = (p5+p6)/2; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_result = pointMappedFromEdge.insert(std::make_pair(fixed_array(h[7],h[6]),pointIndex)); - if(insert_result.second) + insertResultSuccessful = pointMappedFromEdge.insert({{h[7],h[6]},pointIndex }).second; + if(insertResultSuccessful) { p = (p7+p6)/2; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_result = pointMappedFromEdge.insert(std::make_pair(fixed_array(h[4],h[7]),pointIndex)); - if(insert_result.second) + insertResultSuccessful = pointMappedFromEdge.insert({{h[4],h[7]},pointIndex }).second; + if(insertResultSuccessful) { p = (p4+p7)/2; toModel->addPoint(p[0], p[1], p[2]); @@ -187,49 +185,48 @@ void SimpleTesselatedHexaTopologicalMapping::init() } // points mapped from facets - std::pair, int>::iterator, bool> insert_facets_result; - insert_facets_result = pointMappedFromFacet.insert(std::make_pair(fixed_array(h[0], h[1], h[2], h[3]), pointIndex)); - if (insert_facets_result.second) + bool insertFacetsResultSuccessful = pointMappedFromFacet.insert({ {h[0], h[1], h[2], h[3]}, pointIndex }).second; + if (insertFacetsResultSuccessful) { p = (p0+p1+p2+p3)/4; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_facets_result = pointMappedFromFacet.insert(std::make_pair(fixed_array(h[0], h[1], h[5], h[4]), pointIndex)); - if (insert_facets_result.second) + insertFacetsResultSuccessful = pointMappedFromFacet.insert({ {h[0], h[1], h[5], h[4] }, pointIndex }).second; + if (insertFacetsResultSuccessful) { p = (p0+p1+p5+p4)/4; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_facets_result = pointMappedFromFacet.insert(std::make_pair(fixed_array(h[1], h[2], h[6], h[5]), pointIndex)); - if (insert_facets_result.second) + insertFacetsResultSuccessful = pointMappedFromFacet.insert({ {h[1], h[2], h[6], h[5]}, pointIndex }).second; + if (insertFacetsResultSuccessful) { p = (p1+p2+p6+p5)/4; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_facets_result = pointMappedFromFacet.insert(std::make_pair(fixed_array(h[3], h[2], h[6], h[7]), pointIndex)); - if (insert_facets_result.second) + insertFacetsResultSuccessful = pointMappedFromFacet.insert({ {h[3], h[2], h[6], h[7]}, pointIndex }).second; + if (insertFacetsResultSuccessful) { p = (p3+p2+p6+p7)/4; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_facets_result = pointMappedFromFacet.insert(std::make_pair(fixed_array(h[0], h[3], h[7], h[4]), pointIndex)); - if (insert_facets_result.second) + insertFacetsResultSuccessful = pointMappedFromFacet.insert({ {h[0], h[3], h[7], h[4]}, pointIndex }).second; + if (insertFacetsResultSuccessful) { p = (p0+p4+p7+p3)/4; toModel->addPoint(p[0], p[1], p[2]); pointIndex++; } - insert_facets_result = pointMappedFromFacet.insert(std::make_pair(fixed_array(h[4], h[5], h[6], h[7]), pointIndex)); - if (insert_facets_result.second) + insertFacetsResultSuccessful = pointMappedFromFacet.insert({ {h[4], h[5], h[6], h[7]}, pointIndex }).second; + if (insertFacetsResultSuccessful) { p = (p4+p5+p6+p7)/4; toModel->addPoint(p[0], p[1], p[2]); @@ -257,75 +254,75 @@ void SimpleTesselatedHexaTopologicalMapping::init() Vec3d p7(fromModel->getPX(h[7]), fromModel->getPY(h[7]), fromModel->getPZ(h[7])); toModel->addHexa(h[0], - pointMappedFromEdge[fixed_array(h[0],h[1])], - pointMappedFromFacet[fixed_array(h[0],h[1],h[2],h[3])], - pointMappedFromEdge[fixed_array(h[0],h[3])], - pointMappedFromEdge[fixed_array(h[0],h[4])], - pointMappedFromFacet[fixed_array(h[0],h[1],h[5],h[4])], + pointMappedFromEdge[{h[0],h[1]}], + pointMappedFromFacet[{h[0],h[1],h[2],h[3]}], + pointMappedFromEdge[{h[0],h[3]}], + pointMappedFromEdge[{h[0],h[4]}], + pointMappedFromFacet[{h[0],h[1],h[5],h[4]}], pointMappedFromHexa[i], - pointMappedFromFacet[fixed_array(h[0],h[3],h[7],h[4])]); + pointMappedFromFacet[{h[0],h[3],h[7],h[4]}]); - toModel->addHexa(pointMappedFromEdge[fixed_array(h[0],h[1])], + toModel->addHexa(pointMappedFromEdge[{h[0],h[1]}], h[1], - pointMappedFromEdge[fixed_array(h[1],h[2])], - pointMappedFromFacet[fixed_array(h[0],h[1],h[2],h[3])], - pointMappedFromFacet[fixed_array(h[0],h[1],h[5],h[4])], - pointMappedFromEdge[fixed_array(h[1],h[5])], - pointMappedFromFacet[fixed_array(h[1],h[2],h[6],h[5])], + pointMappedFromEdge[{h[1],h[2]}], + pointMappedFromFacet[{h[0],h[1],h[2],h[3]}], + pointMappedFromFacet[{h[0],h[1],h[5],h[4]}], + pointMappedFromEdge[{h[1],h[5]}], + pointMappedFromFacet[{h[1],h[2],h[6],h[5]}], pointMappedFromHexa[i]); - toModel->addHexa(pointMappedFromFacet[fixed_array(h[0],h[1],h[2],h[3])], - pointMappedFromEdge[fixed_array(h[1],h[2])], + toModel->addHexa(pointMappedFromFacet[{h[0],h[1],h[2],h[3]}], + pointMappedFromEdge[{h[1],h[2]}], h[2], - pointMappedFromEdge[fixed_array(h[3],h[2])], + pointMappedFromEdge[{h[3],h[2]}], pointMappedFromHexa[i], - pointMappedFromFacet[fixed_array(h[1],h[2],h[6],h[5])], - pointMappedFromEdge[fixed_array(h[2],h[6])], - pointMappedFromFacet[fixed_array(h[3],h[2],h[6],h[7])]); + pointMappedFromFacet[{h[1],h[2],h[6],h[5]}], + pointMappedFromEdge[{h[2],h[6]}], + pointMappedFromFacet[{h[3],h[2],h[6],h[7]}]); - toModel->addHexa(pointMappedFromEdge[fixed_array(h[0],h[3])], - pointMappedFromFacet[fixed_array(h[0],h[1],h[2],h[3])], - pointMappedFromEdge[fixed_array(h[3],h[2])], + toModel->addHexa(pointMappedFromEdge[{h[0],h[3]}], + pointMappedFromFacet[{h[0],h[1],h[2],h[3]}], + pointMappedFromEdge[{h[3],h[2]}], h[3], - pointMappedFromFacet[fixed_array(h[0],h[3],h[7],h[4])], + pointMappedFromFacet[{h[0],h[3],h[7],h[4]}], pointMappedFromHexa[i], - pointMappedFromFacet[fixed_array(h[3],h[2],h[6],h[7])], - pointMappedFromEdge[fixed_array(h[3],h[7])]); + pointMappedFromFacet[{h[3],h[2],h[6],h[7]}], + pointMappedFromEdge[{h[3],h[7]}]); - toModel->addHexa(pointMappedFromEdge[fixed_array(h[0],h[4])], - pointMappedFromFacet[fixed_array(h[0],h[1],h[5],h[4])], + toModel->addHexa(pointMappedFromEdge[{h[0],h[4]}], + pointMappedFromFacet[{h[0],h[1],h[5],h[4]}], pointMappedFromHexa[i], - pointMappedFromFacet[fixed_array(h[0],h[3],h[7],h[4])], + pointMappedFromFacet[{h[0],h[3],h[7],h[4]}], h[4], - pointMappedFromEdge[fixed_array(h[4],h[5])], - pointMappedFromFacet[fixed_array(h[4],h[5],h[6],h[7])], - pointMappedFromEdge[fixed_array(h[4],h[7])]); + pointMappedFromEdge[{h[4],h[5]}], + pointMappedFromFacet[{h[4],h[5],h[6],h[7]}], + pointMappedFromEdge[{h[4],h[7]}]); - toModel->addHexa(pointMappedFromFacet[fixed_array(h[0],h[1],h[5],h[4])], - pointMappedFromEdge[fixed_array(h[1],h[5])], - pointMappedFromFacet[fixed_array(h[1],h[2],h[6],h[5])], + toModel->addHexa(pointMappedFromFacet[{h[0],h[1],h[5],h[4]}], + pointMappedFromEdge[{h[1],h[5]}], + pointMappedFromFacet[{h[1],h[2],h[6],h[5]}], pointMappedFromHexa[i], - pointMappedFromEdge[fixed_array(h[4],h[5])], + pointMappedFromEdge[{h[4],h[5]}], h[5], - pointMappedFromEdge[fixed_array(h[5],h[6])], - pointMappedFromFacet[fixed_array(h[4],h[5],h[6],h[7])]); + pointMappedFromEdge[{h[5],h[6]}], + pointMappedFromFacet[{h[4],h[5],h[6],h[7]}]); toModel->addHexa(pointMappedFromHexa[i], - pointMappedFromFacet[fixed_array(h[1],h[2],h[6],h[5])], - pointMappedFromEdge[fixed_array(h[2],h[6])], - pointMappedFromFacet[fixed_array(h[3],h[2],h[6],h[7])], - pointMappedFromFacet[fixed_array(h[4],h[5],h[6],h[7])], - pointMappedFromEdge[fixed_array(h[5],h[6])], + pointMappedFromFacet[{h[1],h[2],h[6],h[5]}], + pointMappedFromEdge[{h[2],h[6]}], + pointMappedFromFacet[{h[3],h[2],h[6],h[7]}], + pointMappedFromFacet[{h[4],h[5],h[6],h[7]}], + pointMappedFromEdge[{h[5],h[6]}], h[6], - pointMappedFromEdge[fixed_array(h[7],h[6])]); + pointMappedFromEdge[{h[7],h[6]}]); - toModel->addHexa(pointMappedFromFacet[fixed_array(h[0],h[3],h[7],h[4])], + toModel->addHexa(pointMappedFromFacet[{h[0],h[3],h[7],h[4]}], pointMappedFromHexa[i], - pointMappedFromFacet[fixed_array(h[3],h[2],h[6],h[7])], - pointMappedFromEdge[fixed_array(h[3],h[7])], - pointMappedFromEdge[fixed_array(h[4],h[7])], - pointMappedFromFacet[fixed_array(h[4],h[5],h[6],h[7])], - pointMappedFromEdge[fixed_array(h[7],h[6])], + pointMappedFromFacet[{h[3],h[2],h[6],h[7]}], + pointMappedFromEdge[{h[3],h[7]}], + pointMappedFromEdge[{h[4],h[7]}], + pointMappedFromFacet[{h[4],h[5],h[6],h[7]}], + pointMappedFromEdge[{h[7],h[6]}], h[7]); } diff --git a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SimpleTesselatedHexaTopologicalMapping.h b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SimpleTesselatedHexaTopologicalMapping.h index 3adbbf3bd16f..cc26984b4805 100644 --- a/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SimpleTesselatedHexaTopologicalMapping.h +++ b/Sofa/Component/Mapping/Linear/src/sofa/component/mapping/linear/SimpleTesselatedHexaTopologicalMapping.h @@ -81,10 +81,10 @@ class SOFA_COMPONENT_MAPPING_LINEAR_API SimpleTesselatedHexaTopologicalMapping : * */ protected: - type::vector pointMappedFromPoint; - std::map, int> pointMappedFromEdge; - std::map, int> pointMappedFromFacet; - type::vector pointMappedFromHexa; + type::vector pointMappedFromPoint; + std::map, sofa::Index> pointMappedFromEdge; + std::map, sofa::Index> pointMappedFromFacet; + type::vector pointMappedFromHexa; }; } //namespace sofa::component::mapping::linear From 22d783bb366fae979b31df6b22de60dde5a19d76 Mon Sep 17 00:00:00 2001 From: Olivier Roussel Date: Sun, 5 Nov 2023 22:28:15 +0100 Subject: [PATCH 35/60] [all] Externalize cxxopts (#4273) * Add possibility to use external package of cxxopts before trying fetch * add a cmake option to allow or disable the fetching of dependencies * List fetchable dependencies in cmake option comments. * Apply suggestions from code review Co-authored-by: erik pernod --------- Co-authored-by: erik pernod --- CMakeLists.txt | 5 +++++ Sofa/GUI/Common/CMakeLists.txt | 29 ++++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eae67ddbbe39..ad2fea6d3d7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,11 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LIBRARY_OUTPUT_DIRECTOR # Option for packaging option(SOFA_BUILD_RELEASE_PACKAGE "Run package specific configure" OFF) +# Option to allow some dependencies such as cxxopts to be fetched by cmake if +# the package is not found +option(SOFA_ALLOW_FETCH_DEPENDENCIES "Allow compatible dependencies to be fetched if the package is not found by cmake. + List of dependencies that can be fetched: cxxopts" ON) + # Option to accelerate the compilation # see https://cmake.org/cmake/help/v3.16/command/target_precompile_headers.html # and https://cmake.org/cmake/help/v3.16/prop_tgt/DISABLE_PRECOMPILE_HEADERS.html diff --git a/Sofa/GUI/Common/CMakeLists.txt b/Sofa/GUI/Common/CMakeLists.txt index 0da109387ced..b1eb06b7d1f1 100644 --- a/Sofa/GUI/Common/CMakeLists.txt +++ b/Sofa/GUI/Common/CMakeLists.txt @@ -1,21 +1,24 @@ cmake_minimum_required(VERSION 3.12) project(Sofa.GUI.Common LANGUAGES CXX) -include(FetchContent) -FetchContent_Declare(cxxopts - GIT_REPOSITORY https://github.com/jarro2783/cxxopts - GIT_TAG v3.1.1 -) +find_package(cxxopts 3.1) +if(NOT cxxopts_FOUND AND SOFA_ALLOW_FETCH_DEPENDENCIES) + include(FetchContent) + FetchContent_Declare(cxxopts + GIT_REPOSITORY https://github.com/jarro2783/cxxopts + GIT_TAG v3.1.1 + ) -FetchContent_GetProperties(cxxopts) -if(NOT cxxopts_POPULATED) - FetchContent_Populate(cxxopts) + FetchContent_GetProperties(cxxopts) + if(NOT cxxopts_POPULATED) + FetchContent_Populate(cxxopts) - set(CXXOPTS_BUILD_EXAMPLES OFF CACHE INTERNAL "") - set(CXXOPTS_BUILD_TESTS OFF CACHE INTERNAL "") - set(CXXOPTS_ENABLE_INSTALL ON CACHE INTERNAL "") + set(CXXOPTS_BUILD_EXAMPLES OFF CACHE INTERNAL "") + set(CXXOPTS_BUILD_TESTS OFF CACHE INTERNAL "") + set(CXXOPTS_ENABLE_INSTALL ON CACHE INTERNAL "") - add_subdirectory(${cxxopts_SOURCE_DIR} ${cxxopts_BINARY_DIR}) + add_subdirectory(${cxxopts_SOURCE_DIR} ${cxxopts_BINARY_DIR}) + endif() endif() set(SOFAGUICOMMON_ROOT src/sofa/gui/common) @@ -84,7 +87,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Simulation.Common) target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Component.Setting) target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Component.Collision.Response.Contact) target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.GUI.Component) -target_link_libraries(${PROJECT_NAME} PUBLIC cxxopts) +target_link_libraries(${PROJECT_NAME} PUBLIC cxxopts::cxxopts) target_include_directories(${PROJECT_NAME} PUBLIC "$") target_include_directories(${PROJECT_NAME} PUBLIC "$") From c00d08270bd45ab264d7d8071d9a580a888ea12e Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Thu, 9 Nov 2023 06:47:20 +0900 Subject: [PATCH 36/60] [SofaCUDA] Dont use both version of cublas (legacy or v2) (#4274) use either cublasv2 or legacy, not both Co-authored-by: erik pernod --- applications/plugins/SofaCUDA/sofa/gpu/cuda/mycuda.cu | 2 +- applications/plugins/SofaCUDA/sofa/gpu/cuda/mycuda.h | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/applications/plugins/SofaCUDA/sofa/gpu/cuda/mycuda.cu b/applications/plugins/SofaCUDA/sofa/gpu/cuda/mycuda.cu index 9b680ec7c4a7..0034cb6fa43c 100644 --- a/applications/plugins/SofaCUDA/sofa/gpu/cuda/mycuda.cu +++ b/applications/plugins/SofaCUDA/sofa/gpu/cuda/mycuda.cu @@ -254,7 +254,7 @@ int mycudaInit(int device) } -#ifdef SOFA_GPU_CUBLAS +#if defined(SOFA_GPU_CUBLAS) && !defined(SOFA_GPU_CUBLAS_V2) cublasInit(); #endif return 1; diff --git a/applications/plugins/SofaCUDA/sofa/gpu/cuda/mycuda.h b/applications/plugins/SofaCUDA/sofa/gpu/cuda/mycuda.h index 46fe9da2f1b8..21d87f0738a8 100644 --- a/applications/plugins/SofaCUDA/sofa/gpu/cuda/mycuda.h +++ b/applications/plugins/SofaCUDA/sofa/gpu/cuda/mycuda.h @@ -26,8 +26,12 @@ #include #ifdef SOFA_GPU_CUBLAS -#include +#if __has_include() +#define SOFA_GPU_CUBLAS_V2 #include +#else +#include +#endif #include #endif @@ -88,7 +92,6 @@ extern "C" { extern cusparseMatDescr_t SOFA_GPU_CUDA_API getCusparseMatGeneralDescr(); extern cusparseMatDescr_t SOFA_GPU_CUDA_API getCusparseMatTriangularUpperDescr(); extern cusparseMatDescr_t SOFA_GPU_CUDA_API getCusparseMatTriangularLowerDescr(); - #endif #if defined(NDEBUG) && !defined(CUDA_DEBUG) From b422d3957ece661c4b9f3c444e41b7476f62dd54 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Wed, 22 Nov 2023 13:33:23 +0100 Subject: [PATCH 37/60] [LinearAlgera, Core] Fix linking with LTO on MacOS/Clang (#4293) Fix linking with LTO on macos --- Sofa/framework/Core/CMakeLists.txt | 1 + .../src/sofa/core/topology/TopologyData.cpp | 32 +++++++++++++++++++ .../src/sofa/core/topology/TopologyData.h | 4 +++ .../core/topology/TopologySubsetIndices.cpp | 1 - .../src/sofa/linearalgebra/FullVector.cpp | 2 +- .../src/sofa/linearalgebra/FullVector.h | 2 +- 6 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 Sofa/framework/Core/src/sofa/core/topology/TopologyData.cpp diff --git a/Sofa/framework/Core/CMakeLists.txt b/Sofa/framework/Core/CMakeLists.txt index 88e44c0829cf..8ba69b2f1095 100644 --- a/Sofa/framework/Core/CMakeLists.txt +++ b/Sofa/framework/Core/CMakeLists.txt @@ -306,6 +306,7 @@ set(SOURCE_FILES ${SRC_ROOT}/topology/Topology.cpp ${SRC_ROOT}/topology/TopologyChange.cpp ${SRC_ROOT}/topology/TopologyHandler.cpp + ${SRC_ROOT}/topology/TopologyData.cpp ${SRC_ROOT}/topology/TopologySubsetIndices.cpp ${SRC_ROOT}/visual/Data[DisplayFlags].cpp ${SRC_ROOT}/visual/DisplayFlags.cpp diff --git a/Sofa/framework/Core/src/sofa/core/topology/TopologyData.cpp b/Sofa/framework/Core/src/sofa/core/topology/TopologyData.cpp new file mode 100644 index 000000000000..ac1a0847a0c0 --- /dev/null +++ b/Sofa/framework/Core/src/sofa/core/topology/TopologyData.cpp @@ -0,0 +1,32 @@ +/****************************************************************************** +* SOFA, Simulation Open-Framework Architecture * +* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by * +* the Free Software Foundation; either version 2.1 of the License, or (at * +* your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this program. If not, see . * +******************************************************************************* +* Authors: The SOFA Team and external contributors (see Authors.txt) * +* * +* Contact information: contact@sofa-framework.org * +******************************************************************************/ +#define SOFA_CORE_TOPOLOGY_TOPOLOGYDATA_DEFINITION + +#include + + +namespace sofa::core::topology +{ + +template class SOFA_CORE_API sofa::core::topology::TopologyData < core::topology::BaseMeshTopology::Point, type::vector >; + +} //namespace sofa::core::topology diff --git a/Sofa/framework/Core/src/sofa/core/topology/TopologyData.h b/Sofa/framework/Core/src/sofa/core/topology/TopologyData.h index 645fd16ce9b5..25f5366c8d86 100644 --- a/Sofa/framework/Core/src/sofa/core/topology/TopologyData.h +++ b/Sofa/framework/Core/src/sofa/core/topology/TopologyData.h @@ -164,5 +164,9 @@ template< class VecT > using QuadData = TopologyData using TetrahedronData = TopologyData; template< class VecT > using HexahedronData = TopologyData; +#if !defined(SOFA_CORE_TOPOLOGY_TOPOLOGYDATA_DEFINITION) +extern template class SOFA_CORE_API sofa::core::topology::TopologyData < core::topology::BaseMeshTopology::Point, type::vector >; +#endif + } //namespace sofa::core::topology diff --git a/Sofa/framework/Core/src/sofa/core/topology/TopologySubsetIndices.cpp b/Sofa/framework/Core/src/sofa/core/topology/TopologySubsetIndices.cpp index 38770cc257ca..59c5dfc48f18 100644 --- a/Sofa/framework/Core/src/sofa/core/topology/TopologySubsetIndices.cpp +++ b/Sofa/framework/Core/src/sofa/core/topology/TopologySubsetIndices.cpp @@ -85,7 +85,6 @@ void TopologySubsetIndices::updateLastIndex(Index posLastIndex, Index newGlobalI } template class SOFA_CORE_API sofa::core::topology::TopologyDataHandler < core::topology::BaseMeshTopology::Point, type::vector >; -template class SOFA_CORE_API sofa::core::topology::TopologyData < core::topology::BaseMeshTopology::Point, type::vector >; //template class SOFA_CORE_API sofa::core::topology::BaseTopologyData < type::vector >; } //namespace sofa::core::topology diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/FullVector.cpp b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/FullVector.cpp index 35e24709a93b..104a3d23deb9 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/FullVector.cpp +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/FullVector.cpp @@ -19,7 +19,7 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#define SOFABASELINEARSOLVER_FULLMATRIX_DEFINITION +#define SOFA_LINEARALGEBRA_FULLVECTOR_DEFINITION #include namespace sofa::linearalgebra diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/FullVector.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/FullVector.h index 628a702fe363..8f4e7b0a71e7 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/FullVector.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/FullVector.h @@ -220,7 +220,7 @@ class FullVector : public linearalgebra::BaseVector SOFA_LINEARALGEBRA_API std::ostream& operator <<(std::ostream& out, const FullVector& v); SOFA_LINEARALGEBRA_API std::ostream& operator <<(std::ostream& out, const FullVector& v); -#if !defined(SOFABASELINEARSOLVER_FULLMATRIX_DEFINITION) +#if !defined(SOFA_LINEARALGEBRA_FULLVECTOR_DEFINITION) extern template class SOFA_LINEARALGEBRA_API FullVector; extern template class SOFA_LINEARALGEBRA_API FullVector; #endif From 5a3f36cf171ed3fae2d6ec91d62804d748cb5b20 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 23 Nov 2023 17:42:08 +0100 Subject: [PATCH 38/60] [LinearSolver] Remove CSparse-based linear solvers (#4258) * [LinearSolver.Direct] Remove CSparse based solvers * Remove csparse extlib * Fetchable CSparseSolvers plugin * Remove references of SparseLUSolver * Remove references to SparseCholeskySolver * Remove csparse * Try to fix on Linux * Update the compat * [LinearSolver.Direct] Remove CSparse based solvers * Fix direct solver --- .../SofaSparseSolver/SparseCholeskySolver.h | 4 +- .../src/SofaSparseSolver/SparseLUSolver.h | 4 +- .../src/SofaSparseSolver/SparseLUSolver.inl | 4 +- .../LinearSolver/Direct/CMakeLists.txt | 6 +- ...mponent.LinearSolver.DirectConfig.cmake.in | 4 - .../Direct/extlibs/csparse/CMakeLists.txt | 32 - .../Direct/extlibs/csparse/COPYING.txt | 3 - .../extlibs/csparse/CSparseConfig.cmake.in | 12 - .../Direct/extlibs/csparse/UFconfig.h | 118 - .../Direct/extlibs/csparse/csparse.c | 2122 ----------------- .../Direct/extlibs/csparse/csparse.h | 144 -- .../LinearSolver/Direct/extlibs/csparse/ldl.c | 507 ---- .../LinearSolver/Direct/extlibs/csparse/ldl.h | 111 - .../direct/EigenDirectSparseSolver.inl | 9 +- .../direct/PrecomputedLinearSolver.h | 4 +- .../direct/PrecomputedLinearSolver.inl | 19 +- .../direct/SparseCholeskySolver.cpp | 44 - .../direct/SparseCholeskySolver.h | 61 +- .../direct/SparseCholeskySolver.inl | 206 +- .../linearsolver/direct/SparseCommon.cpp | 17 +- .../linearsolver/direct/SparseCommon.h | 9 +- .../linearsolver/direct/SparseLDLSolverImpl.h | 1 - .../linearsolver/direct/SparseLUSolver.cpp | 46 - .../linearsolver/direct/SparseLUSolver.h | 89 +- .../linearsolver/direct/SparseLUSolver.inl | 234 +- .../PrecomputedWarpPreconditioner.h | 4 +- .../PrecomputedWarpPreconditioner.inl | 21 +- .../src/sofa/core/topology/TopologyData.cpp | 2 +- .../src/sofa/helper/ComponentChange.cpp | 6 +- applications/plugins/CMakeLists.txt | 1 + .../ExternalProjectConfig.cmake.in | 14 + .../beam10x10x46-warp-preconditioner-CUDA.scn | 1 - .../examples/ComplianceMatrixExporter.scn | 4 +- .../examples/ComplianceMatrixImage.scn | 4 +- .../examples/FillReducingOrdering.scn | 6 +- .../Lagrangian/InextensiblePendulum.scn | 4 +- .../Direct/FEMBAR_SparseCholeskySolver.scn | 8 - .../Direct/FEMBAR_SparseLUSolver.scn | 8 - .../NonLinear/DistanceFromTargetMapping.scn | 4 +- .../FEM/RestShapeSpringsForceField3.scn | 4 +- .../Spring/RestShapeSpringsForceField2.scn | 4 +- .../RegressionStateScenes.regression-tests | 2 - 42 files changed, 89 insertions(+), 3818 deletions(-) delete mode 100644 Sofa/Component/LinearSolver/Direct/extlibs/csparse/CMakeLists.txt delete mode 100644 Sofa/Component/LinearSolver/Direct/extlibs/csparse/COPYING.txt delete mode 100644 Sofa/Component/LinearSolver/Direct/extlibs/csparse/CSparseConfig.cmake.in delete mode 100644 Sofa/Component/LinearSolver/Direct/extlibs/csparse/UFconfig.h delete mode 100644 Sofa/Component/LinearSolver/Direct/extlibs/csparse/csparse.c delete mode 100644 Sofa/Component/LinearSolver/Direct/extlibs/csparse/csparse.h delete mode 100644 Sofa/Component/LinearSolver/Direct/extlibs/csparse/ldl.c delete mode 100644 Sofa/Component/LinearSolver/Direct/extlibs/csparse/ldl.h delete mode 100644 Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.cpp delete mode 100644 Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.cpp create mode 100644 applications/plugins/CSparseSolvers/ExternalProjectConfig.cmake.in delete mode 100644 examples/Component/LinearSolver/Direct/FEMBAR_SparseCholeskySolver.scn delete mode 100644 examples/Component/LinearSolver/Direct/FEMBAR_SparseLUSolver.scn diff --git a/Sofa/Component/Compat/src/SofaSparseSolver/SparseCholeskySolver.h b/Sofa/Component/Compat/src/SofaSparseSolver/SparseCholeskySolver.h index c3829690869b..e08378ac130c 100644 --- a/Sofa/Component/Compat/src/SofaSparseSolver/SparseCholeskySolver.h +++ b/Sofa/Component/Compat/src/SofaSparseSolver/SparseCholeskySolver.h @@ -23,4 +23,6 @@ #include -SOFA_DISABLED_HEADER("v22.06", "v23.06", "sofa/component/linearsolver/direct/SparseCholeskySolver.h") +SOFA_PRAGMA_ERROR( \ + "This header has been DISABLED since v23.12. " \ + "To fix this error you must use the CSparseSolvers plugins. " ) diff --git a/Sofa/Component/Compat/src/SofaSparseSolver/SparseLUSolver.h b/Sofa/Component/Compat/src/SofaSparseSolver/SparseLUSolver.h index 406f08044d2e..4e21871483e7 100644 --- a/Sofa/Component/Compat/src/SofaSparseSolver/SparseLUSolver.h +++ b/Sofa/Component/Compat/src/SofaSparseSolver/SparseLUSolver.h @@ -23,4 +23,6 @@ #include -SOFA_DISABLED_HEADER("v22.06", "v23.06", "sofa/component/linearsolver/direct/SparseLUSolver.h") +SOFA_PRAGMA_ERROR( \ + "This header has been DISABLED since v23.12. " \ + "To fix this error you must use the CSparseSolvers plugins. " ) diff --git a/Sofa/Component/Compat/src/SofaSparseSolver/SparseLUSolver.inl b/Sofa/Component/Compat/src/SofaSparseSolver/SparseLUSolver.inl index 4610b2cc02d5..a50573db9b03 100644 --- a/Sofa/Component/Compat/src/SofaSparseSolver/SparseLUSolver.inl +++ b/Sofa/Component/Compat/src/SofaSparseSolver/SparseLUSolver.inl @@ -23,4 +23,6 @@ #include -SOFA_DISABLED_HEADER("v22.06", "v23.06", "sofa/component/linearsolver/direct/SparseLUSolver.inl") +SOFA_PRAGMA_ERROR( \ + "This header has been DISABLED since v23.12. " \ + "To fix this error you must use the CSparseSolvers plugins. " ) diff --git a/Sofa/Component/LinearSolver/Direct/CMakeLists.txt b/Sofa/Component/LinearSolver/Direct/CMakeLists.txt index 898a186778f5..51fa093de067 100644 --- a/Sofa/Component/LinearSolver/Direct/CMakeLists.txt +++ b/Sofa/Component/LinearSolver/Direct/CMakeLists.txt @@ -50,14 +50,10 @@ set(SOURCE_FILES ${SOFACOMPONENTLINEARSOLVERDIRECT_SOURCE_DIR}/MatrixLinearSystem[BTDMatrix].cpp ${SOFACOMPONENTLINEARSOLVERDIRECT_SOURCE_DIR}/PrecomputedLinearSolver.cpp ${SOFACOMPONENTLINEARSOLVERDIRECT_SOURCE_DIR}/SVDLinearSolver.cpp - ${SOFACOMPONENTLINEARSOLVERDIRECT_SOURCE_DIR}/SparseCholeskySolver.cpp ${SOFACOMPONENTLINEARSOLVERDIRECT_SOURCE_DIR}/SparseCommon.cpp ${SOFACOMPONENTLINEARSOLVERDIRECT_SOURCE_DIR}/SparseLDLSolver.cpp - ${SOFACOMPONENTLINEARSOLVERDIRECT_SOURCE_DIR}/SparseLUSolver.cpp ${SOFACOMPONENTLINEARSOLVERDIRECT_SOURCE_DIR}/TypedMatrixLinearSystem[BTDMatrix].cpp ) -add_subdirectory(extlibs/csparse) -sofa_set_01(SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE VALUE TRUE) sofa_find_package(metis QUIET) # Unix users can have an installed version of metis if(NOT metis_FOUND) @@ -75,7 +71,7 @@ sofa_find_package(Sofa.Component.LinearSolver.Iterative REQUIRED) # Only for Mat add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES} ${WRAPPER_FILES}) target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Simulation.Core Sofa.Component.LinearSolver.Iterative) -target_link_libraries(${PROJECT_NAME} PUBLIC metis csparse) +target_link_libraries(${PROJECT_NAME} PUBLIC metis) target_link_libraries(${PROJECT_NAME} PUBLIC Threads::Threads) sofa_create_package_with_targets( diff --git a/Sofa/Component/LinearSolver/Direct/Sofa.Component.LinearSolver.DirectConfig.cmake.in b/Sofa/Component/LinearSolver/Direct/Sofa.Component.LinearSolver.DirectConfig.cmake.in index 0b4b584fb08a..4025df0d43e6 100644 --- a/Sofa/Component/LinearSolver/Direct/Sofa.Component.LinearSolver.DirectConfig.cmake.in +++ b/Sofa/Component/LinearSolver/Direct/Sofa.Component.LinearSolver.DirectConfig.cmake.in @@ -8,14 +8,10 @@ find_package(Sofa.Component.LinearSolver.Iterative QUIET REQUIRED) find_package(Threads QUIET REQUIRED) set(SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_METIS @SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_METIS@) -set(SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE @SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE@) if(SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_METIS) find_package(Metis QUIET REQUIRED HINTS "${CMAKE_CURRENT_LIST_DIR}/..") endif() -if(SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE) - find_package(CSparse QUIET REQUIRED HINTS "${CMAKE_CURRENT_LIST_DIR}/..") -endif() if(NOT TARGET @PROJECT_NAME@) include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") diff --git a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/CMakeLists.txt b/Sofa/Component/LinearSolver/Direct/extlibs/csparse/CMakeLists.txt deleted file mode 100644 index 266aa286dd46..000000000000 --- a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -cmake_minimum_required(VERSION 3.12) -project(csparse VERSION 1.2.0) - -set(HEADER_FILES - csparse.h - ldl.h - UFconfig.h) - -set(SOURCE_FILES - csparse.c - ldl.c) - -# The code must be relocatable if we want to link a shared library against it. -if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xGNU" OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang") - add_compile_options(-fPIC) -endif() - -add_library(${PROJECT_NAME} STATIC ${HEADER_FILES} ${SOURCE_FILES}) -target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC "$") -target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC "$") - -if(WIN32) - # remove warnings about deprecation (CRT,etc) - target_compile_options(${PROJECT_NAME} PRIVATE "/wd4996") -endif() - -sofa_create_package_with_targets( - PACKAGE_NAME CSparse - PACKAGE_VERSION ${PROJECT_VERSION} - TARGETS ${PROJECT_NAME} AUTO_SET_TARGET_PROPERTIES - INCLUDE_INSTALL_DIR "extlibs/CSparse" - ) diff --git a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/COPYING.txt b/Sofa/Component/LinearSolver/Direct/extlibs/csparse/COPYING.txt deleted file mode 100644 index 49ba8beccea8..000000000000 --- a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/COPYING.txt +++ /dev/null @@ -1,3 +0,0 @@ -CSPARSE: a Concise Sparse matrix package. -Copyright (c) 2006, Timothy A. Davis. -http://www.cise.ufl.edu/research/sparse/CSparse diff --git a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/CSparseConfig.cmake.in b/Sofa/Component/LinearSolver/Direct/extlibs/csparse/CSparseConfig.cmake.in deleted file mode 100644 index af532008d06d..000000000000 --- a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/CSparseConfig.cmake.in +++ /dev/null @@ -1,12 +0,0 @@ -# CMake package configuration file for the csparse library - -@PACKAGE_INIT@ - -if(NOT TARGET csparse) - include("${CMAKE_CURRENT_LIST_DIR}/CSparseTargets.cmake") -endif() - -check_required_components(csparse) - -set(CSparse_LIBRARIES csparse) -set(CSparse_INCLUDE_DIRS @PACKAGE_CSPARSE_INCLUDE_DIR@) diff --git a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/UFconfig.h b/Sofa/Component/LinearSolver/Direct/extlibs/csparse/UFconfig.h deleted file mode 100644 index 54208d58b79c..000000000000 --- a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/UFconfig.h +++ /dev/null @@ -1,118 +0,0 @@ -/* ========================================================================== */ -/* === UFconfig.h =========================================================== */ -/* ========================================================================== */ - -/* Configuration file for SuiteSparse: a Suite of Sparse matrix packages - * (AMD, COLAMD, CCOLAMD, CAMD, CHOLMOD, UMFPACK, CXSparse, and others). - * - * UFconfig.h provides the definition of the long integer. On most systems, - * a C program can be compiled in LP64 mode, in which long's and pointers are - * both 64-bits, and int's are 32-bits. Windows 64, however, uses the LLP64 - * model, in which int's and long's are 32-bits, and long long's and pointers - * are 64-bits. - * - * SuiteSparse packages that include long integer versions are - * intended for the LP64 mode. However, as a workaround for Windows 64 - * (and perhaps other systems), the long integer can be redefined. - * - * If _WIN64 is defined, then the __int64 type is used instead of long. - * - * The long integer can also be defined at compile time. For example, this - * could be added to UFconfig.mk: - * - * CFLAGS = -O -D'UF_long=long long' -D'UF_long_max=9223372036854775801' \ - * -D'UF_long_id="%lld"' - * - * This file defines UF_long as either long (on all but _WIN64) or - * __int64 on Windows 64. The intent is that a UF_long is always a 64-bit - * integer in a 64-bit code. ptrdiff_t might be a better choice than long; - * it is always the same size as a pointer. - * - * This file also defines the SUITESPARSE_VERSION and related definitions. - * - * Copyright (c) 2007, University of Florida. No licensing restrictions - * apply to this file or to the UFconfig directory. Author: Timothy A. Davis. - */ - -#ifndef _UFCONFIG_H -#define _UFCONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* ========================================================================== */ -/* === UF_long ============================================================== */ -/* ========================================================================== */ - -#ifndef UF_long - -#ifdef _WIN64 - -#define UF_long __int64 -#define UF_long_max _I64_MAX -#define UF_long_id "%I64d" - -#else - -#define UF_long long -#define UF_long_max LONG_MAX -#define UF_long_id "%ld" - -#endif -#endif - -/* ========================================================================== */ -/* === SuiteSparse version ================================================== */ -/* ========================================================================== */ - -/* SuiteSparse is not a package itself, but a collection of packages, some of - * which must be used together (UMFPACK requires AMD, CHOLMOD requires AMD, - * COLAMD, CAMD, and CCOLAMD, etc). A version number is provided here for the - * collection itself. The versions of packages within each version of - * SuiteSparse are meant to work together. Combining one packge from one - * version of SuiteSparse, with another package from another version of - * SuiteSparse, may or may not work. - * - * SuiteSparse Version 3.2.0 contains the following packages: - * - * AMD version 2.2.0 - * CAMD version 2.2.0 - * COLAMD version 2.7.1 - * CCOLAMD version 2.7.1 - * CHOLMOD version 1.7.0 - * CSparse version 2.2.1 - * CXSparse version 2.2.1 - * KLU version 1.0.1 - * BTF version 1.0.1 - * LDL version 2.0.1 - * UFconfig version number is the same as SuiteSparse - * UMFPACK version 5.2.0 - * RBio version 1.1.1 - * UFcollection version 1.1.1 - * LINFACTOR version 1.1.0 - * MESHND version 1.1.0 - * SSMULT version 1.1.0 - * MATLAB_Tools no specific version number - * SuiteSparseQR version 1.1.0 - * - * Other package dependencies: - * BLAS required by CHOLMOD and UMFPACK - * LAPACK required by CHOLMOD - * METIS 4.0.1 required by CHOLMOD (optional) and KLU (optional) - */ - -#define SUITESPARSE_DATE "Sept 20, 2008" -#define SUITESPARSE_VER_CODE(main,sub) ((main) * 1000 + (sub)) -#define SUITESPARSE_MAIN_VERSION 3 -#define SUITESPARSE_SUB_VERSION 2 -#define SUITESPARSE_SUBSUB_VERSION 0 -#define SUITESPARSE_VERSION \ - SUITESPARSE_VER_CODE(SUITESPARSE_MAIN_VERSION,SUITESPARSE_SUB_VERSION) - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/csparse.c b/Sofa/Component/LinearSolver/Direct/extlibs/csparse/csparse.c deleted file mode 100644 index 14c7b342622f..000000000000 --- a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/csparse.c +++ /dev/null @@ -1,2122 +0,0 @@ -# include -# include -# include -# include - -# include "csparse.h" - -cs *cs_add ( const cs *A, const cs *B, double alpha, double beta ) -/* - Purpose: - - CS_ADD computes C = alpha*A + beta*B for sparse A and B. - - Reference: - - Timothy Davis, - Direct Methods for Sparse Linear Systems, - SIAM, Philadelphia, 2006. -*/ -{ - int p, j, nz = 0, anz, *Cp, *Ci, *Bp, m, n, bnz, *w, values ; - double *x, *Bx, *Cx ; - cs *C ; - if (!A || !B) return (NULL) ; /* check inputs */ - m = A->m ; anz = A->p [A->n] ; - n = B->n ; Bp = B->p ; Bx = B->x ; bnz = Bp [n] ; - w = cs_calloc (m, sizeof (int)) ; - values = (A->x != NULL) && (Bx != NULL) ; - x = values ? cs_malloc (m, sizeof (double)) : NULL ; - C = cs_spalloc (m, n, anz + bnz, values, 0) ; - if (!C || !w || (values && !x)) return (cs_done (C, w, x, 0)) ; - Cp = C->p ; Ci = C->i ; Cx = C->x ; - for (j = 0 ; j < n ; j++) - { - Cp [j] = nz ; /* column j of C starts here */ - nz = cs_scatter (A, j, alpha, w, x, j+1, C, nz) ; /* alpha*A(:,j)*/ - nz = cs_scatter (B, j, beta, w, x, j+1, C, nz) ; /* beta*B(:,j) */ - if (values) for (p = Cp [j] ; p < nz ; p++) Cx [p] = x [Ci [p]] ; - } - Cp [n] = nz ; /* finalize the last column of C */ - cs_sprealloc (C, 0) ; /* remove extra space from C */ - return (cs_done (C, w, x, 1)) ; /* success; free workspace, return C */ -} -static int cs_wclear (int mark, int lemax, int *w, int n) -/* - Purpose: - - CS_WCLEAR clears W. - - Reference: - - Timothy Davis, - Direct Methods for Sparse Linear Systems, - SIAM, Philadelphia, 2006. -*/ -{ - int k ; - if (mark < 2 || (mark + lemax < 0)) - { - for (k = 0 ; k < n ; k++) if (w [k] != 0) w [k] = 1 ; - mark = 2 ; - } - return (mark) ; /* at this point, w [0..n-1] < mark holds */ -} - -/* keep off-diagonal entries; drop diagonal entries */ -static int cs_diag (int i, int j, double aij, void * other) -{ - return (i != j); - (void)aij; (void)other; // unused parameters -} - -/* p = amd(A+A') if symmetric is true, or amd(A'A) otherwise */ -int *cs_amd ( const cs *A, int order ) -/* - Purpose: - - CS_AMD carries out the approximate minimum degree algorithm. - - Reference: - - Timothy Davis, - Direct Methods for Sparse Linear Systems, - SIAM, Philadelphia, 2006. - - Parameters: - - Input, int ORDER: - -1:natural, - 0:Cholesky, - 1:LU, - 2:QR -*/ -{ - cs *C, *A2, *AT ; - int *Cp, *Ci, *last, *ww, *len, *nv, *next, *P, *head, *elen, *degree, *w, - *hhead, *ATp, *ATi, d, dk, dext, lemax = 0, e, elenk, eln, i, j, k, k1, - k2, k3, jlast, ln, dense, nzmax, mindeg = 0, nvi, nvj, nvk, mark, wnvi, - ok, cnz, nel = 0, p, p1, p2, p3, p4, pj, pk, pk1, pk2, pn, q, n, m ; - unsigned int h ; - /* --- Construct matrix C ----------------------------------------------- */ - if (!A || order < 0) return (NULL) ; /* check inputs; quick return */ - AT = cs_transpose (A, 0) ; /* compute A' */ - if (!AT) return (NULL) ; - m = A->m ; n = A->n ; - dense = (int)CS_MAX (16, 10 * sqrt ((double) n)) ; /* find dense threshold */ - dense = CS_MIN (n-2, dense) ; - if (order == 0 && n == m) - { - C = cs_add (A, AT, 0, 0) ; /* C = A+A' */ - } - else if (order == 1) - { - ATp = AT->p ; /* drop dense columns from AT */ - ATi = AT->i ; - for (p2 = 0, j = 0 ; j < m ; j++) - { - p = ATp [j] ; /* column j of AT starts here */ - ATp [j] = p2 ; /* new column j starts here */ - if (ATp [j+1] - p > dense) continue ; /* skip dense col j */ - for ( ; p < ATp [j+1] ; p++) ATi [p2++] = ATi [p] ; - } - ATp [m] = p2 ; /* finalize AT */ - A2 = cs_transpose (AT, 0) ; /* A2 = AT' */ - C = A2 ? cs_multiply (AT, A2) : NULL ; /* C=A'*A with no dense rows */ - cs_spfree (A2) ; - } - else - { - C = cs_multiply (AT, A) ; /* C=A'*A */ - } - cs_spfree (AT) ; - if (!C) return (NULL) ; - P = cs_malloc (n+1, sizeof (int)) ; /* allocate result */ - ww = cs_malloc (8*(n+1), sizeof (int)) ;/* get workspace */ - len = ww ; nv = ww + (n+1) ; next = ww + 2*(n+1) ; - head = ww + 3*(n+1) ; elen = ww + 4*(n+1) ; degree = ww + 5*(n+1) ; - w = ww + 6*(n+1) ; hhead = ww + 7*(n+1) ; - last = P ; /* use P as workspace for last */ - cs_fkeep (C, &cs_diag, NULL) ; /* drop diagonal entries */ - Cp = C->p ; - cnz = Cp [n] ; - if (!cs_sprealloc (C, cnz+cnz/5+2*n)) return (cs_idone (P, C, ww, 0)) ; - /* --- Initialize quotient graph ---------------------------------------- */ - for (k = 0 ; k < n ; k++) len [k] = Cp [k+1] - Cp [k] ; - len [n] = 0 ; - nzmax = C->nzmax ; - Ci = C->i ; - for (i = 0 ; i <= n ; i++) - { - head [i] = -1 ; /* degree list i is empty */ - last [i] = -1 ; - next [i] = -1 ; - hhead [i] = -1 ; /* hash list i is empty */ - nv [i] = 1 ; /* node i is just one node */ - w [i] = 1 ; /* node i is alive */ - elen [i] = 0 ; /* Ek of node i is empty */ - degree [i] = len [i] ; /* degree of node i */ - } - mark = cs_wclear (0, 0, w, n) ; /* clear w */ - elen [n] = -2 ; /* n is a dead element */ - Cp [n] = -1 ; /* n is a root of assembly tree */ - w [n] = 0 ; /* n is a dead element */ - /* --- Initialize degree lists ------------------------------------------ */ - for (i = 0 ; i < n ; i++) - { - d = degree [i] ; - if (d == 0) /* node i is empty */ - { - elen [i] = -2 ; /* element i is dead */ - nel++ ; - Cp [i] = -1 ; /* i is a root of assemby tree */ - w [i] = 0 ; - } - else if (d > dense) /* node i is dense */ - { - nv [i] = 0 ; /* absorb i into element n */ - elen [i] = -1 ; /* node i is dead */ - nel++ ; - Cp [i] = CS_FLIP (n) ; - nv [n]++ ; - } - else - { - if (head [d] != -1) last [head [d]] = i ; - next [i] = head [d] ; /* put node i in degree list d */ - head [d] = i ; - } - } - while (nel < n) /* while (selecting pivots) do */ - { - /* --- Select node of minimum approximate degree -------------------- */ - for (k = -1 ; mindeg < n && (k = head [mindeg]) == -1 ; mindeg++) ; - if (next [k] != -1) last [next [k]] = -1 ; - head [mindeg] = next [k] ; /* remove k from degree list */ - elenk = elen [k] ; /* elenk = |Ek| */ - nvk = nv [k] ; /* # of nodes k represents */ - nel += nvk ; /* nv[k] nodes of A eliminated */ - /* --- Garbage collection ------------------------------------------- */ - if (elenk > 0 && cnz + mindeg >= nzmax) - { - for (j = 0 ; j < n ; j++) - { - if ((p = Cp [j]) >= 0) /* j is a live node or element */ - { - Cp [j] = Ci [p] ; /* save first entry of object */ - Ci [p] = CS_FLIP (j) ; /* first entry is now CS_FLIP(j) */ - } - } - for (q = 0, p = 0 ; p < cnz ; ) /* scan all of memory */ - { - if ((j = CS_FLIP (Ci [p++])) >= 0) /* found object j */ - { - Ci [q] = Cp [j] ; /* restore first entry of object */ - Cp [j] = q++ ; /* new pointer to object j */ - for (k3 = 0 ; k3 < len [j]-1 ; k3++) Ci [q++] = Ci [p++] ; - } - } - cnz = q ; /* Ci [cnz...nzmax-1] now free */ - } - /* --- Construct new element ---------------------------------------- */ - dk = 0 ; - nv [k] = -nvk ; /* flag k as in Lk */ - p = Cp [k] ; - pk1 = (elenk == 0) ? p : cnz ; /* do in place if elen[k] == 0 */ - pk2 = pk1 ; - for (k1 = 1 ; k1 <= elenk + 1 ; k1++) - { - if (k1 > elenk) - { - e = k ; /* search the nodes in k */ - pj = p ; /* list of nodes starts at Ci[pj]*/ - ln = len [k] - elenk ; /* length of list of nodes in k */ - } - else - { - e = Ci [p++] ; /* search the nodes in e */ - pj = Cp [e] ; - ln = len [e] ; /* length of list of nodes in e */ - } - for (k2 = 1 ; k2 <= ln ; k2++) - { - i = Ci [pj++] ; - if ((nvi = nv [i]) <= 0) continue ; /* node i dead, or seen */ - dk += nvi ; /* degree[Lk] += size of node i */ - nv [i] = -nvi ; /* negate nv[i] to denote i in Lk*/ - Ci [pk2++] = i ; /* place i in Lk */ - if (next [i] != -1) last [next [i]] = last [i] ; - if (last [i] != -1) /* remove i from degree list */ - { - next [last [i]] = next [i] ; - } - else - { - head [degree [i]] = next [i] ; - } - } - if (e != k) - { - Cp [e] = CS_FLIP (k) ; /* absorb e into k */ - w [e] = 0 ; /* e is now a dead element */ - } - } - if (elenk != 0) cnz = pk2 ; /* Ci [cnz...nzmax] is free */ - degree [k] = dk ; /* external degree of k - |Lk\i| */ - Cp [k] = pk1 ; /* element k is in Ci[pk1..pk2-1] */ - len [k] = pk2 - pk1 ; - elen [k] = -2 ; /* k is now an element */ - /* --- Find set differences ----------------------------------------- */ - mark = cs_wclear (mark, lemax, w, n) ; /* clear w if necessary */ - for (pk = pk1 ; pk < pk2 ; pk++) /* scan 1: find |Le\Lk| */ - { - i = Ci [pk] ; - if ((eln = elen [i]) <= 0) continue ;/* skip if elen[i] empty */ - nvi = -nv [i] ; /* nv [i] was negated */ - wnvi = mark - nvi ; - for (p = Cp [i] ; p <= Cp [i] + eln - 1 ; p++) /* scan Ei */ - { - e = Ci [p] ; - if (w [e] >= mark) - { - w [e] -= nvi ; /* decrement |Le\Lk| */ - } - else if (w [e] != 0) /* ensure e is a live element */ - { - w [e] = degree [e] + wnvi ; /* 1st time e seen in scan 1 */ - } - } - } - /* --- Degree update ------------------------------------------------ */ - for (pk = pk1 ; pk < pk2 ; pk++) /* scan2: degree update */ - { - i = Ci [pk] ; /* consider node i in Lk */ - p1 = Cp [i] ; - p2 = p1 + elen [i] - 1 ; - pn = p1 ; - for (h = 0, d = 0, p = p1 ; p <= p2 ; p++) /* scan Ei */ - { - e = Ci [p] ; - if (w [e] != 0) /* e is an unabsorbed element */ - { - dext = w [e] - mark ; /* dext = |Le\Lk| */ - if (dext > 0) - { - d += dext ; /* sum up the set differences */ - Ci [pn++] = e ; /* keep e in Ei */ - h += e ; /* compute the hash of node i */ - } - else - { - Cp [e] = CS_FLIP (k) ; /* aggressive absorb. e->k */ - w [e] = 0 ; /* e is a dead element */ - } - } - } - elen [i] = pn - p1 + 1 ; /* elen[i] = |Ei| */ - p3 = pn ; - p4 = p1 + len [i] ; - for (p = p2 + 1 ; p < p4 ; p++) /* prune edges in Ai */ - { - j = Ci [p] ; - if ((nvj = nv [j]) <= 0) continue ; /* node j dead or in Lk */ - d += nvj ; /* degree(i) += |j| */ - Ci [pn++] = j ; /* place j in node list of i */ - h += j ; /* compute hash for node i */ - } - if (d == 0) /* check for mass elimination */ - { - Cp [i] = CS_FLIP (k) ; /* absorb i into k */ - nvi = -nv [i] ; - dk -= nvi ; /* |Lk| -= |i| */ - nvk += nvi ; /* |k| += nv[i] */ - nel += nvi ; - nv [i] = 0 ; - elen [i] = -1 ; /* node i is dead */ - } - else - { - degree [i] = CS_MIN (degree [i], d) ; /* update degree(i) */ - Ci [pn] = Ci [p3] ; /* move first node to end */ - Ci [p3] = Ci [p1] ; /* move 1st el. to end of Ei */ - Ci [p1] = k ; /* add k as 1st element in of Ei */ - len [i] = pn - p1 + 1 ; /* new len of adj. list of node i */ - h %= n ; /* finalize hash of i */ - next [i] = hhead [h] ; /* place i in hash bucket */ - hhead [h] = i ; - last [i] = h ; /* save hash of i in last[i] */ - } - } /* scan2 is done */ - degree [k] = dk ; /* finalize |Lk| */ - lemax = CS_MAX (lemax, dk) ; - mark = cs_wclear (mark+lemax, lemax, w, n) ; /* clear w */ - /* --- Supernode detection ------------------------------------------ */ - for (pk = pk1 ; pk < pk2 ; pk++) - { - i = Ci [pk] ; - if (nv [i] >= 0) continue ; /* skip if i is dead */ - h = last [i] ; /* scan hash bucket of node i */ - i = hhead [h] ; - hhead [h] = -1 ; /* hash bucket will be empty */ - for ( ; i != -1 && next [i] != -1 ; i = next [i], mark++) - { - ln = len [i] ; - eln = elen [i] ; - for (p = Cp[i]+1 ; p <= Cp[i]+ln-1 ; p++) w [Ci [p]] = mark ; - jlast = i ; - for (j = next [i] ; j != -1 ; ) /* compare i with all j */ - { - ok = (len [j] == ln) && (elen [j] == eln) ; - for (p = Cp [j] + 1 ; ok && p <= Cp [j] + ln - 1 ; p++) - { - if (w [Ci [p]] != mark) ok = 0 ; /* compare i and j*/ - } - if (ok) /* i and j are identical */ - { - Cp [j] = CS_FLIP (i) ; /* absorb j into i */ - nv [i] += nv [j] ; - nv [j] = 0 ; - elen [j] = -1 ; /* node j is dead */ - j = next [j] ; /* delete j from hash bucket */ - next [jlast] = j ; - } - else - { - jlast = j ; /* j and i are different */ - j = next [j] ; - } - } - } - } - /* --- Finalize new element------------------------------------------ */ - for (p = pk1, pk = pk1 ; pk < pk2 ; pk++) /* finalize Lk */ - { - i = Ci [pk] ; - if ((nvi = -nv [i]) <= 0) continue ;/* skip if i is dead */ - nv [i] = nvi ; /* restore nv[i] */ - d = degree [i] + dk - nvi ; /* compute external degree(i) */ - d = CS_MIN (d, n - nel - nvi) ; - if (head [d] != -1) last [head [d]] = i ; - next [i] = head [d] ; /* put i back in degree list */ - last [i] = -1 ; - head [d] = i ; - mindeg = CS_MIN (mindeg, d) ; /* find new minimum degree */ - degree [i] = d ; - Ci [p++] = i ; /* place i in Lk */ - } - nv [k] = nvk ; /* # nodes absorbed into k */ - if ((len [k] = p-pk1) == 0) /* length of adj list of element k*/ - { - Cp [k] = -1 ; /* k is a root of the tree */ - w [k] = 0 ; /* k is now a dead element */ - } - if (elenk != 0) cnz = p ; /* free unused space in Lk */ - } - /* --- Postordering ----------------------------------------------------- */ - for (i = 0 ; i < n ; i++) Cp [i] = CS_FLIP (Cp [i]) ;/* fix assembly tree */ - for (j = 0 ; j <= n ; j++) head [j] = -1 ; - for (j = n ; j >= 0 ; j--) /* place unordered nodes in lists */ - { - if (nv [j] > 0) continue ; /* skip if j is an element */ - next [j] = head [Cp [j]] ; /* place j in list of its parent */ - head [Cp [j]] = j ; - } - for (e = n ; e >= 0 ; e--) /* place elements in lists */ - { - if (nv [e] <= 0) continue ; /* skip unless e is an element */ - if (Cp [e] != -1) - { - next [e] = head [Cp [e]] ; /* place e in list of its parent */ - head [Cp [e]] = e ; - } - } - for (k = 0, i = 0 ; i <= n ; i++) /* postorder the assembly tree */ - { - if (Cp [i] == -1) k = cs_tdfs (i, k, head, next, P, w) ; - } - return (cs_idone (P, C, ww, 1)) ; -} - -/* compute nonzero pattern of L(k,:) */ -static -int cs_ereach (const cs *A, int k, const int *parent, int *s, int *w, - double *x, int top) -{ - int i, p, len, *Ap = A->p, *Ai = A->i ; - double *Ax = A->x ; - for (p = Ap [k] ; p < Ap [k+1] ; p++) /* get pattern of L(k,:) */ - { - i = Ai [p] ; /* A(i,k) is nonzero */ - if (i > k) continue ; /* only use upper triangular part of A */ - x [i] = Ax [p] ; /* x(i) = A(i,k) */ - for (len = 0 ; w [i] != k ; i = parent [i]) /* traverse up etree */ - { - s [len++] = i ; /* L(k,i) is nonzero */ - w [i] = k ; /* mark i as visited */ - } - while (len > 0) s [--top] = s [--len] ; /* push path onto stack */ - } - return (top) ; /* s [top..n-1] contains pattern of L(k,:)*/ -} - -/* L = chol (A, [Pinv parent cp]), Pinv is optional */ -csn *cs_chol (const cs *A, const css *S) -{ - double d, lki, *Lx, *x ; - int top, i, p, k, n, *Li, *Lp, *cp, *Pinv, *w, *s, *c, *parent ; - cs *L, *C, *E ; - csn *N ; - if (!A || !S || !S->cp || !S->parent) return (NULL) ; /* check inputs */ - n = A->n ; - N = cs_calloc (1, sizeof (csn)) ; - w = cs_malloc (3*n, sizeof (int)) ; s = w + n, c = w + 2*n ; - x = cs_malloc (n, sizeof (double)) ; - cp = S->cp ; Pinv = S->Pinv ; parent = S->parent ; - C = Pinv ? cs_symperm (A, Pinv, 1) : ((cs *) A) ; - E = Pinv ? C : NULL ; - if (!N || !w || !x || !C) return (cs_ndone (N, E, w, x, 0)) ; - N->L = L = cs_spalloc (n, n, cp [n], 1, 0) ; - if (!L) return (cs_ndone (N, E, w, x, 0)) ; - Lp = L->p ; Li = L->i ; Lx = L->x ; - for (k = 0 ; k < n ; k++) - { - /* --- Nonzero pattern of L(k,:) ------------------------------------ */ - Lp [k] = c [k] = cp [k] ; /* column k of L starts here */ - x [k] = 0 ; /* x (0:k) is now zero */ - w [k] = k ; /* mark node k as visited */ - top = cs_ereach (C, k, parent, s, w, x, n) ; /* find row k of L*/ - d = x [k] ; /* d = C(k,k) */ - x [k] = 0 ; /* clear workspace for k+1st iteration */ - /* --- Triangular solve --------------------------------------------- */ - for ( ; top < n ; top++) /* solve L(0:k-1,0:k-1) * x = C(:,k) */ - { - i = s [top] ; /* s [top..n-1] is pattern of L(k,:) */ - lki = x [i] / Lx [Lp [i]] ; /* L(k,i) = x (i) / L(i,i) */ - x [i] = 0 ; /* clear workspace for k+1st iteration */ - for (p = Lp [i] + 1 ; p < c [i] ; p++) - { - x [Li [p]] -= Lx [p] * lki ; - } - d -= lki * lki ; /* d = d - L(k,i)*L(k,i) */ - p = c [i]++ ; - Li [p] = k ; /* store L(k,i) in column i */ - Lx [p] = lki ; - } - /* --- Compute L(k,k) ----------------------------------------------- */ - if (d <= 0) return (cs_ndone (N, E, w, x, 0)) ; /* not pos def */ - p = c [k]++ ; - Li [p] = k ; /* store L(k,k) = sqrt (d) in column k */ - Lx [p] = sqrt (d) ; - } - Lp [n] = cp [n] ; /* finalize L */ - return (cs_ndone (N, E, w, x, 1)) ; /* success: free E,w,x; return N */ -} - - -/* x=A\b where A is symmetric positive definite; b overwritten with solution */ -int cs_cholsol (const cs *A, double *b, int order) -{ - double *x ; - css *S ; - csn *N ; - int n, ok ; - if (!A || !b) return (0) ; /* check inputs */ - n = A->n ; - S = cs_schol (A, order) ; /* ordering and symbolic analysis */ - N = cs_chol (A, S) ; /* numeric Cholesky factorization */ - x = cs_malloc (n, sizeof (double)) ; - ok = (S && N && x) ; - if (ok) - { - cs_ipvec (n, S->Pinv, b, x) ; /* x = P*b */ - cs_lsolve (N->L, x) ; /* x = L\x */ - cs_ltsolve (N->L, x) ; /* x = L'\x */ - cs_pvec (n, S->Pinv, x, b) ; /* b = P'*x */ - } - cs_free (x) ; - cs_sfree (S) ; - cs_nfree (N) ; - return (ok) ; -} - -/* process edge (j,i) of the matrix */ -static void cs_cedge (int j, int i, const int *first, int *maxfirst, int *delta, - int *prevleaf, int *ancestor) -{ - int q, s, sparent, jprev ; - if (i <= j || first [j] <= maxfirst [i]) return ; - maxfirst [i] = first [j] ; /* update max first[j] seen so far */ - jprev = prevleaf [i] ; /* j is a leaf of the ith subtree */ - delta [j]++ ; /* A(i,j) is in the skeleton matrix */ - if (jprev != -1) - { - /* q = least common ancestor of jprev and j */ - for (q = jprev ; q != ancestor [q] ; q = ancestor [q]) ; - for (s = jprev ; s != q ; s = sparent) - { - sparent = ancestor [s] ; /* path compression */ - ancestor [s] = q ; - } - delta [q]-- ; /* decrement to account for overlap in q */ - } - prevleaf [i] = j ; /* j is now previous leaf of ith subtree */ -} - -/* colcount = column counts of LL'=A or LL'=A'A, given parent & post ordering */ -int *cs_counts (const cs *A, const int *parent, const int *post, int ata) -{ - int i, j, k, p, n, m, ii, s, *ATp, *ATi, *maxfirst, *prevleaf, *ancestor, - *head = NULL, *next = NULL, *colcount, *w, *first, *delta ; - cs *AT ; - if (!A || !parent || !post) return (NULL) ; /* check inputs */ - m = A->m ; n = A->n ; - s = 4*n + (ata ? (n+m+1) : 0) ; - w = cs_malloc (s, sizeof (int)) ; first = w+3*n ; /* get workspace */ - ancestor = w ; maxfirst = w+n ; prevleaf = w+2*n ; - delta = colcount = cs_malloc (n, sizeof (int)) ; /* allocate result */ - AT = cs_transpose (A, 0) ; - if (!AT || !colcount || !w) return (cs_idone (colcount, AT, w, 1)) ; - for (k = 0 ; k < s ; k++) w [k] = -1 ; /* clear workspace w [0..s-1] */ - for (k = 0 ; k < n ; k++) /* find first [j] */ - { - j = post [k] ; - delta [j] = (first [j] == -1) ? 1 : 0 ; /* delta[j]=1 if j is a leaf */ - for ( ; j != -1 && first [j] == -1 ; j = parent [j]) first [j] = k ; - } - ATp = AT->p ; ATi = AT->i ; - if (ata) - { - head = w+4*n ; next = w+5*n+1 ; - for (k = 0 ; k < n ; k++) w [post [k]] = k ; /* invert post */ - for (i = 0 ; i < m ; i++) - { - k = n ; /* k = least postordered column in row i */ - for (p = ATp [i] ; p < ATp [i+1] ; p++) k = CS_MIN (k, w [ATi [p]]); - next [i] = head [k] ; /* place row i in link list k */ - head [k] = i ; - } - } - for (i = 0 ; i < n ; i++) ancestor [i] = i ; /* each node in its own set */ - for (k = 0 ; k < n ; k++) - { - j = post [k] ; /* j is the kth node in postordered etree */ - if (parent [j] != -1) delta [parent [j]]-- ; /* j is not a root */ - if (ata) - { - for (ii = head [k] ; ii != -1 ; ii = next [ii]) - { - for (p = ATp [ii] ; p < ATp [ii+1] ; p++) - cs_cedge (j, ATi [p], first, maxfirst, delta, prevleaf, - ancestor) ; - } - } - else - { - for (p = ATp [j] ; p < ATp [j+1] ; p++) - cs_cedge (j, ATi [p], first, maxfirst, delta, prevleaf, - ancestor) ; - } - if (parent [j] != -1) ancestor [j] = parent [j] ; - } - for (j = 0 ; j < n ; j++) /* sum up delta's of each child */ - { - if (parent [j] != -1) colcount [parent [j]] += colcount [j] ; - } - return (cs_idone (colcount, AT, w, 1)) ; /* success: free workspace */ -} - -/* p [0..n] = cumulative sum of c [0..n-1], and then copy p [0..n-1] into c */ -int cs_cumsum (int *p, int *c, int n) -{ - int i, nz = 0 ; - if (!p || !c) return (-1) ; /* check inputs */ - for (i = 0 ; i < n ; i++) - { - p [i] = nz ; - nz += c [i] ; - c [i] = p [i] ; - } - p [n] = nz ; - return (nz) ; /* return sum (c [0..n-1]) */ -} - -/* depth-first-search of the graph of a matrix, starting at node j */ -int cs_dfs (int j, cs *L, int top, int *xi, int *pstack, const int *Pinv) -{ - int i, p, p2, done, jnew, head = 0, *Lp, *Li ; - if (!L || !xi || !pstack) return (-1) ; - Lp = L->p ; Li = L->i ; - xi [0] = j ; /* initialize the recursion stack */ - while (head >= 0) - { - j = xi [head] ; /* get j from the top of the recursion stack */ - jnew = Pinv ? (Pinv [j]) : j ; - if (!CS_MARKED(Lp,j)) - { - CS_MARK (Lp,j) ; /* mark node j as visited */ - pstack [head] = (jnew < 0) ? 0 : CS_UNFLIP (Lp [jnew]) ; - } - done = 1 ; /* node j done if no unvisited neighbors */ - p2 = (jnew < 0) ? 0 : CS_UNFLIP (Lp [jnew+1]) ; - for (p = pstack [head] ; p < p2 ; p++) /* examine all neighbors of j */ - { - i = Li [p] ; /* consider neighbor node i */ - if (CS_MARKED (Lp,i)) continue ; /* skip visited node i */ - pstack [head] = p ; /* pause depth-first search of node j */ - xi [++head] = i ; /* start dfs at node i */ - done = 0 ; /* node j is not done */ - break ; /* break, to start dfs (i) */ - } - if (done) /* depth-first search at node j is done */ - { - head-- ; /* remove j from the recursion stack */ - xi [--top] = j ; /* and place in the output stack */ - } - } - return (top) ; -} - -/* breadth-first search for coarse decomposition (C0,C1,R1 or R0,R3,C3) */ -static int cs_bfs (const cs *A, int n, int *wi, int *wj, int *queue, - const int *imatch, const int *jmatch, int mark) -{ - int *Ap, *Ai, head = 0, tail = 0, j, i, p, j2 ; - cs *C ; - for (j = 0 ; j < n ; j++) /* place all unmatched nodes in queue */ - { - if (imatch [j] >= 0) continue ; /* skip j if matched */ - wj [j] = 0 ; /* j in set C0 (R0 if transpose) */ - queue [tail++] = j ; /* place unmatched col j in queue */ - } - if (tail == 0) return (1) ; /* quick return if no unmatched nodes */ - C = (mark == 1) ? ((cs *) A) : cs_transpose (A, 0) ; - if (!C) return (0) ; /* bfs of C=A' to find R0,R3,C3 */ - Ap = C->p ; Ai = C->i ; - while (head < tail) /* while queue is not empty */ - { - j = queue [head++] ; /* get the head of the queue */ - for (p = Ap [j] ; p < Ap [j+1] ; p++) - { - i = Ai [p] ; - if (wi [i] >= 0) continue ; /* skip if i is marked */ - wi [i] = mark ; /* i in set R1 (C3 if transpose) */ - j2 = jmatch [i] ; /* traverse alternating path to j2 */ - if (wj [j2] >= 0) continue ;/* skip j2 if it is marked */ - wj [j2] = mark ; /* j2 in set C1 (R3 if transpose) */ - queue [tail++] = j2 ; /* add j2 to queue */ - } - } - if (mark != 1) cs_spfree (C) ; /* free A' if it was created */ - return (1) ; -} - -/* collect matched rows and columns into P and Q */ -static void cs_matched (int m, const int *wi, const int *jmatch, int *P, int *Q, - int *cc, int *rr, int set, int mark) -{ - int kc = cc [set], i ; - int kr = rr [set-1] ; - for (i = 0 ; i < m ; i++) - { - if (wi [i] != mark) continue ; /* skip if i is not in R set */ - P [kr++] = i ; - Q [kc++] = jmatch [i] ; - } - cc [set+1] = kc ; - rr [set] = kr ; -} - - -static void cs_unmatched (int m, const int *wi, int *P, int *rr, int set) -/* - Purpose: - - CS_UNMATCHED collects unmatched rows into the permutation vector P. -*/ -{ - int i, kr = rr [set] ; - for (i = 0 ; i < m ; i++) if (wi [i] == 0) P [kr++] = i ; - rr [set+1] = kr ; -} - -/* return 1 if row i is in R2 */ -static int cs_rprune (int i, int j, double aij, void *other) -{ - int *rr = (int *) other ; - return (i >= rr [1] && i < rr [2]) ; - (void)j; (void)aij; // unused parameters -} - -/* Given A, find coarse dmperm */ -csd *cs_dmperm (const cs *A) -{ - int m, n, i, j, k, p, cnz, nc, *jmatch, *imatch, *wi, *wj, *Pinv, *Cp, *Ci, - *Ps, *Rs, nb1, nb2, *P, *Q, *cc, *rr, *R, *S, ok ; - cs *C ; - csd *D, *scc ; - /* --- Maximum matching ------------------------------------------------- */ - if (!A) return (NULL) ; /* check inputs */ - m = A->m ; n = A->n ; - D = cs_dalloc (m, n) ; /* allocate result */ - if (!D) return (NULL) ; - P = D->P ; Q = D->Q ; R = D->R ; S = D->S ; cc = D->cc ; rr = D->rr ; - jmatch = cs_maxtrans (A) ; /* max transversal */ - imatch = jmatch + m ; /* imatch = inverse of jmatch */ - if (!jmatch) return (cs_ddone (D, NULL, jmatch, 0)) ; - /* --- Coarse decomposition --------------------------------------------- */ - wi = R ; wj = S ; /* use R and S as workspace */ - for (j = 0 ; j < n ; j++) wj [j] = -1 ; /* unmark all cols for bfs */ - for (i = 0 ; i < m ; i++) wi [i] = -1 ; /* unmark all rows for bfs */ - cs_bfs (A, n, wi, wj, Q, imatch, jmatch, 1) ; /* find C0, C1, R1 */ - ok = cs_bfs (A, m, wj, wi, P, jmatch, imatch, 3) ; /* find R0, R3, C3 */ - if (!ok) return (cs_ddone (D, NULL, jmatch, 0)) ; - cs_unmatched (n, wj, Q, cc, 0) ; /* unmatched set C0 */ - cs_matched (m, wi, jmatch, P, Q, cc, rr, 1, 1) ; /* set R1 and C1 */ - cs_matched (m, wi, jmatch, P, Q, cc, rr, 2, -1) ; /* set R2 and C2 */ - cs_matched (m, wi, jmatch, P, Q, cc, rr, 3, 3) ; /* set R3 and C3 */ - cs_unmatched (m, wi, P, rr, 3) ; /* unmatched set R0 */ - cs_free (jmatch) ; - /* --- Fine decomposition ----------------------------------------------- */ - Pinv = cs_pinv (P, m) ; /* Pinv=P' */ - if (!Pinv) return (cs_ddone (D, NULL, NULL, 0)) ; - C = cs_permute (A, Pinv, Q, 0) ;/* C=A(P,Q) (it will hold A(R2,C2)) */ - cs_free (Pinv) ; - if (!C) return (cs_ddone (D, NULL, NULL, 0)) ; - Cp = C->p ; Ci = C->i ; - nc = cc [3] - cc [2] ; /* delete cols C0, C1, and C3 from C */ - if (cc [2] > 0) for (j = cc [2] ; j <= cc [3] ; j++) Cp [j-cc[2]] = Cp [j] ; - C->n = nc ; - if (rr [2] - rr [1] < m) /* delete rows R0, R1, and R3 from C */ - { - cs_fkeep (C, cs_rprune, rr) ; - cnz = Cp [nc] ; - if (rr [1] > 0) for (p = 0 ; p < cnz ; p++) Ci [p] -= rr [1] ; - } - C->m = nc ; - scc = cs_scc (C) ; /* find strongly-connected components of C*/ - if (!scc) return (cs_ddone (D, C, NULL, 0)) ; - /* --- Combine coarse and fine decompositions --------------------------- */ - Ps = scc->P ; /* C(Ps,Ps) is the permuted matrix */ - Rs = scc->R ; /* kth block is Rs[k]..Rs[k+1]-1 */ - nb1 = scc->nb ; /* # of blocks of A(*/ - for (k = 0 ; k < nc ; k++) wj [k] = Q [Ps [k] + cc [2]] ; /* combine */ - for (k = 0 ; k < nc ; k++) Q [k + cc [2]] = wj [k] ; - for (k = 0 ; k < nc ; k++) wi [k] = P [Ps [k] + rr [1]] ; - for (k = 0 ; k < nc ; k++) P [k + rr [1]] = wi [k] ; - nb2 = 0 ; /* create the fine block partitions */ - R [0] = 0 ; - S [0] = 0 ; - if (cc [2] > 0) nb2++ ; /* leading coarse block A (R1, [C0 C1]) */ - for (k = 0 ; k < nb1 ; k++) /* coarse block A (R2,C2) */ - { - R [nb2] = Rs [k] + rr [1] ; /* A (R2,C2) splits into nb1 fine blocks */ - S [nb2] = Rs [k] + cc [2] ; - nb2++ ; - } - if (rr [2] < m) - { - R [nb2] = rr [2] ; /* trailing coarse block A ([R3 R0], C3) */ - S [nb2] = cc [3] ; - nb2++ ; - } - R [nb2] = m ; - S [nb2] = n ; - D->nb = nb2 ; - cs_dfree (scc) ; - return (cs_ddone (D, C, NULL, 1)) ; -} - -static int cs_tol (int i, int j, double aij, void *tol) -{ - return (fabs (aij) > *((double *) tol)) ; - (void)i; (void)j; // unused parameters -} -int cs_droptol (cs *A, double tol) -{ - return (cs_fkeep (A, &cs_tol, &tol)) ; /* keep all large entries */ -} - -static int cs_nonzero (int i, int j, double aij, void *other) -{ - return (aij != 0) ; - (void)i; (void)j; (void)other; // unused parameters -} -int cs_dropzeros (cs *A) -{ - return (cs_fkeep (A, &cs_nonzero, NULL)) ; /* keep all nonzero entries */ -} -int cs_dupl (cs *A) -/* - Purpose: - - CS_DUPL removes duplicate entries from A. - - Reference: - - Timothy Davis, - Direct Methods for Sparse Linear Systems, - SIAM, Philadelphia, 2006. -*/ -{ - int i, j, p, q, nz = 0, n, m, *Ap, *Ai, *w ; - double *Ax ; - if (!A) return (0) ; /* check inputs */ - m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; - w = cs_malloc (m, sizeof (int)) ; /* get workspace */ - if (!w) return (0) ; /* out of memory */ - for (i = 0 ; i < m ; i++) w [i] = -1 ; /* row i not yet seen */ - for (j = 0 ; j < n ; j++) - { - q = nz ; /* column j will start at q */ - for (p = Ap [j] ; p < Ap [j+1] ; p++) - { - i = Ai [p] ; /* A(i,j) is nonzero */ - if (w [i] >= q) - { - Ax [w [i]] += Ax [p] ; /* A(i,j) is a duplicate */ - } - else - { - w [i] = nz ; /* record where row i occurs */ - Ai [nz] = i ; /* keep A(i,j) */ - Ax [nz++] = Ax [p] ; - } - } - Ap [j] = q ; /* record start of column j */ - } - Ap [n] = nz ; /* finalize A */ - cs_free (w) ; /* free workspace */ - return (cs_sprealloc (A, 0)) ; /* remove extra space from A */ -} - -/* add an entry to a triplet matrix; return 1 if ok, 0 otherwise */ -int cs_entry (cs *T, int i, int j, double x) -{ - if (!T || (T->nz >= T->nzmax && !cs_sprealloc (T, 2*(T->nzmax)))) return(0); - if (T->x) T->x [T->nz] = x ; - T->i [T->nz] = i ; - T->p [T->nz++] = j ; - T->m = CS_MAX (T->m, i+1) ; - T->n = CS_MAX (T->n, j+1) ; - return (1) ; -} - -/* compute the etree of A (using triu(A), or A'A without forming A'A */ -int *cs_etree (const cs *A, int ata) -{ - int i, k, p, m, n, inext, *Ap, *Ai, *w, *parent, *ancestor, *prev ; - if (!A) return (NULL) ; /* check inputs */ - m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; - parent = cs_malloc (n, sizeof (int)) ; - w = cs_malloc (n + (ata ? m : 0), sizeof (int)) ; - ancestor = w ; prev = w + n ; - if (!w || !parent) return (cs_idone (parent, NULL, w, 0)) ; - if (ata) for (i = 0 ; i < m ; i++) prev [i] = -1 ; - for (k = 0 ; k < n ; k++) - { - parent [k] = -1 ; /* node k has no parent yet */ - ancestor [k] = -1 ; /* nor does k have an ancestor */ - for (p = Ap [k] ; p < Ap [k+1] ; p++) - { - i = ata ? (prev [Ai [p]]) : (Ai [p]) ; - for ( ; i != -1 && i < k ; i = inext) /* traverse from i to k */ - { - inext = ancestor [i] ; /* inext = ancestor of i */ - ancestor [i] = k ; /* path compression */ - if (inext == -1) parent [i] = k ; /* no anc., parent is k */ - } - if (ata) prev [Ai [p]] = k ; - } - } - return (cs_idone (parent, NULL, w, 1)) ; -} - -/* drop entries for which fkeep(A(i,j)) is false; return nz if OK, else -1 */ -int cs_fkeep (cs *A, int (*fkeep) (int, int, double, void *), void *other) -{ - int j, p, nz = 0, n, *Ap, *Ai ; - double *Ax ; - if (!A || !fkeep) return (-1) ; /* check inputs */ - n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; - for (j = 0 ; j < n ; j++) - { - p = Ap [j] ; /* get current location of col j */ - Ap [j] = nz ; /* record new location of col j */ - for ( ; p < Ap [j+1] ; p++) - { - if (fkeep (Ai [p], j, Ax ? Ax [p] : 1, other)) - { - if (Ax) Ax [nz] = Ax [p] ; /* keep A(i,j) */ - Ai [nz++] = Ai [p] ; - } - } - } - return (Ap [n] = nz) ; /* finalize A and return nnz(A) */ -} - -/* y = A*x+y */ -int cs_gaxpy (const cs *A, const double *x, double *y) -{ - int p, j, n, *Ap, *Ai ; - double *Ax ; - if (!A || !x || !y) return (0) ; /* check inputs */ - n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; - for (j = 0 ; j < n ; j++) - { - for (p = Ap [j] ; p < Ap [j+1] ; p++) - { - y [Ai [p]] += Ax [p] * x [j] ; - } - } - return (1) ; -} - -/* apply the ith Householder vector to x */ -int cs_happly (const cs *V, int i, double beta, double *x) -{ - int p, *Vp, *Vi ; - double *Vx, tau = 0 ; - if (!V || !x) return (0) ; /* check inputs */ - Vp = V->p ; Vi = V->i ; Vx = V->x ; - for (p = Vp [i] ; p < Vp [i+1] ; p++) /* tau = v'*x */ - { - tau += Vx [p] * x [Vi [p]] ; - } - tau *= beta ; /* tau = beta*(v'*x) */ - for (p = Vp [i] ; p < Vp [i+1] ; p++) /* x = x - v*tau */ - { - x [Vi [p]] -= Vx [p] * tau ; - } - return (1) ; -} - -/* create a Householder reflection [v,beta,s]=house(x), overwrite x with v, - * where (I-beta*v*v')*x = s*x. See Algo 5.1.1, Golub & Van Loan, 3rd ed. */ -double cs_house (double *x, double *beta, int n) -{ - double s, sigma = 0 ; - int i ; - if (!x || !beta) return (-1) ; /* check inputs */ - for (i = 1 ; i < n ; i++) sigma += x [i] * x [i] ; - if (sigma == 0) - { - s = fabs (x [0]) ; /* s = |x(0)| */ - (*beta) = (x [0] <= 0) ? 2 : 0 ; - x [0] = 1 ; - } - else - { - s = sqrt (x [0] * x [0] + sigma) ; /* s = norm (x) */ - x [0] = (x [0] <= 0) ? (x [0] - s) : (-sigma / (x [0] + s)) ; - (*beta) = -1. / (s * x [0]) ; - } - return (s) ; -} - -/* x(P) = b, for dense vectors x and b; P=NULL denotes identity */ -int cs_ipvec (int n, const int *P, const double *b, double *x) -{ - int k ; - if (!x || !b) return (0) ; /* check inputs */ - for (k = 0 ; k < n ; k++) x [P ? P [k] : k] = b [k] ; - return (1) ; -} -cs *cs_load ( FILE *f ) -/* - Purpose: - - CS_LOAD loads a triplet matrix from a file. - - Reference: - - Timothy Davis, - Direct Methods for Sparse Linear Systems, - SIAM, Philadelphia, 2006. -*/ -{ - int i, j ; - double x ; - cs *T ; - if (!f) return (NULL) ; - T = cs_spalloc (0, 0, 1, 1, 1) ; - while (fscanf (f, "%d %d %lg\n", &i, &j, &x) == 3) - { - if (!cs_entry (T, i, j, x)) return (cs_spfree (T)) ; - } - return (T) ; -} -int cs_lsolve ( const cs *L, double *x ) -/* - Purpose: - - CS_LSOLVE solves L*x=b. - - Discussion: - - On input, X contains the right hand side, and on output, the solution. - - Reference: - - Timothy Davis, - Direct Methods for Sparse Linear Systems, - SIAM, Philadelphia, 2006. -*/ -{ - int p, j, n, *Lp, *Li ; - double *Lx ; - if (!L || !x) return (0) ; /* check inputs */ - n = L->n ; Lp = L->p ; Li = L->i ; Lx = L->x ; - for (j = 0 ; j < n ; j++) - { - x [j] /= Lx [Lp [j]] ; - for (p = Lp [j]+1 ; p < Lp [j+1] ; p++) - { - x [Li [p]] -= Lx [p] * x [j] ; - } - } - return (1) ; -} -int cs_ltsolve ( const cs *L, double *x ) -/* - Purpose: - - CS_LTSOLVE solves L'*x=b. - - Discussion: - - On input, X contains the right hand side, and on output, the solution. - - Reference: - - Timothy Davis, - Direct Methods for Sparse Linear Systems, - SIAM, Philadelphia, 2006. -*/ -{ - int p, j, n, *Lp, *Li ; - double *Lx ; - if (!L || !x) return (0) ; /* check inputs */ - n = L->n ; Lp = L->p ; Li = L->i ; Lx = L->x ; - for (j = n-1 ; j >= 0 ; j--) - { - for (p = Lp [j]+1 ; p < Lp [j+1] ; p++) - { - x [j] -= Lx [p] * x [Li [p]] ; - } - x [j] /= Lx [Lp [j]] ; - } - return (1) ; -} - -/* [L,U,Pinv]=lu(A, [Q lnz unz]). lnz and unz can be guess */ -csn *cs_lu (const cs *A, const css *S, double tol) -{ - cs *L, *U ; - csn *N ; - double pivot, *Lx, *Ux, *x, a, t ; - int *Lp, *Li, *Up, *Ui, *Pinv, *xi, *Q, n, ipiv, k, top, p, i, col, lnz,unz; - if (!A || !S) return (NULL) ; /* check inputs */ - n = A->n ; - Q = S->Q ; lnz = S->lnz ; unz = S->unz ; - x = cs_malloc (n, sizeof (double)) ; - xi = cs_malloc (2*n, sizeof (int)) ; - N = cs_calloc (1, sizeof (csn)) ; - if (!x || !xi || !N) return (cs_ndone (N, NULL, xi, x, 0)) ; - N->L = L = cs_spalloc (n, n, lnz, 1, 0) ; /* initial L and U */ - N->U = U = cs_spalloc (n, n, unz, 1, 0) ; - N->Pinv = Pinv = cs_malloc (n, sizeof (int)) ; - if (!L || !U || !Pinv) return (cs_ndone (N, NULL, xi, x, 0)) ; - Lp = L->p ; Up = U->p ; - for (i = 0 ; i < n ; i++) x [i] = 0 ; /* clear workspace */ - for (i = 0 ; i < n ; i++) Pinv [i] = -1 ; /* no rows pivotal yet */ - for (k = 0 ; k <= n ; k++) Lp [k] = 0 ; /* no cols of L yet */ - lnz = unz = 0 ; - for (k = 0 ; k < n ; k++) /* compute L(:,k) and U(:,k) */ - { - /* --- Triangular solve --------------------------------------------- */ - Lp [k] = lnz ; /* L(:,k) starts here */ - Up [k] = unz ; /* U(:,k) starts here */ - if ((lnz + n > L->nzmax && !cs_sprealloc (L, 2*L->nzmax + n)) || - (unz + n > U->nzmax && !cs_sprealloc (U, 2*U->nzmax + n))) - { - return (cs_ndone (N, NULL, xi, x, 0)) ; - } - Li = L->i ; Lx = L->x ; Ui = U->i ; Ux = U->x ; - col = Q ? (Q [k]) : k ; - top = cs_splsolve (L, A, col, xi, x, Pinv) ; /* x = L\A(:,col) */ - /* --- Find pivot --------------------------------------------------- */ - ipiv = -1 ; - a = -1 ; - for (p = top ; p < n ; p++) - { - i = xi [p] ; /* x(i) is nonzero */ - if (Pinv [i] < 0) /* row i is not pivotal */ - { - if ((t = fabs (x [i])) > a) - { - a = t ; /* largest pivot candidate so far */ - ipiv = i ; - } - } - else /* x(i) is the entry U(Pinv[i],k) */ - { - Ui [unz] = Pinv [i] ; - Ux [unz++] = x [i] ; - } - } - if (ipiv == -1 || a <= 0) return (cs_ndone (N, NULL, xi, x, 0)) ; - if (Pinv [col] < 0 && fabs (x [col]) >= a*tol) ipiv = col ; - /* --- Divide by pivot ---------------------------------------------- */ - pivot = x [ipiv] ; /* the chosen pivot */ - Ui [unz] = k ; /* last entry in U(:,k) is U(k,k) */ - Ux [unz++] = pivot ; - Pinv [ipiv] = k ; /* ipiv is the kth pivot row */ - Li [lnz] = ipiv ; /* first entry in L(:,k) is L(k,k) = 1 */ - Lx [lnz++] = 1 ; - for (p = top ; p < n ; p++) /* L(k+1:n,k) = x / pivot */ - { - i = xi [p] ; - if (Pinv [i] < 0) /* x(i) is an entry in L(:,k) */ - { - Li [lnz] = i ; /* save unpermuted row in L */ - Lx [lnz++] = x [i] / pivot ; /* scale pivot column */ - } - x [i] = 0 ; /* x [0..n-1] = 0 for next k */ - } - } - /* --- Finalize L and U ------------------------------------------------- */ - Lp [n] = lnz ; - Up [n] = unz ; - Li = L->i ; /* fix row indices of L for final Pinv */ - for (p = 0 ; p < lnz ; p++) Li [p] = Pinv [Li [p]] ; - cs_sprealloc (L, 0) ; /* remove extra space from L and U */ - cs_sprealloc (U, 0) ; - return (cs_ndone (N, NULL, xi, x, 1)) ; /* success */ -} - -/* x=A\b where A is unsymmetric; b overwritten with solution */ -int cs_lusol (const cs *A, double *b, int order, double tol) -{ - double *x ; - css *S ; - csn *N ; - int n, ok ; - if (!A || !b) return (0) ; /* check inputs */ - n = A->n ; - S = cs_sqr (A, order, 0) ; /* ordering and symbolic analysis */ - N = cs_lu (A, S, tol) ; /* numeric LU factorization */ - x = cs_malloc (n, sizeof (double)) ; - ok = (S && N && x) ; - if (ok) - { - cs_ipvec (n, N->Pinv, b, x) ; /* x = P*b */ - cs_lsolve (N->L, x) ; /* x = L\x */ - cs_usolve (N->U, x) ; /* x = U\x */ - cs_ipvec (n, S->Q, x, b) ; /* b = Q*x */ - } - cs_free (x) ; - cs_sfree (S) ; - cs_nfree (N) ; - return (ok) ; -} - -#ifdef MATLAB_MEX_FILE -#define malloc mxMalloc -#define free mxFree -#define realloc mxRealloc -#define calloc mxCalloc -#endif - -/* wrapper for malloc */ -void *cs_malloc (int n, size_t size) -{ - return (CS_OVERFLOW (n,size) ? NULL : malloc (CS_MAX (n,1) * size)) ; -} - -/* wrapper for calloc */ -void *cs_calloc (int n, size_t size) -{ - return (CS_OVERFLOW (n,size) ? NULL : calloc (CS_MAX (n,1), size)) ; -} - -/* wrapper for free */ -void *cs_free (void *p) -{ - if (p) free (p) ; /* free p if it is not already NULL */ - return (NULL) ; /* return NULL to simplify the use of cs_free */ -} - -/* wrapper for realloc */ -void *cs_realloc (void *p, int n, size_t size, int *ok) -{ - void *p2 ; - *ok = !CS_OVERFLOW (n,size) ; /* guard against int overflow */ - if (!(*ok)) return (p) ; /* p unchanged if n too large */ - p2 = realloc (p, CS_MAX (n,1) * size) ; /* realloc the block */ - *ok = (p2 != NULL) ; - return ((*ok) ? p2 : p) ; /* return original p if failure */ -} - -/* find an augmenting path starting at column k and extend the match if found */ -static void cs_augment (int k, const cs *A, int *jmatch, int *cheap, int *w, - int *js, int *is, int *ps) -{ - int found = 0, p, i = -1, *Ap = A->p, *Ai = A->i, head = 0, j ; - js [0] = k ; /* start with just node k in jstack */ - while (head >= 0) - { - /* --- Start (or continue) depth-first-search at node j ------------- */ - j = js [head] ; /* get j from top of jstack */ - if (w [j] != k) /* 1st time j visited for kth path */ - { - w [j] = k ; /* mark j as visited for kth path */ - for (p = cheap [j] ; p < Ap [j+1] && !found ; p++) - { - i = Ai [p] ; /* try a cheap assignment (i,j) */ - found = (jmatch [i] == -1) ; - } - cheap [j] = p ; /* start here next time j is traversed*/ - if (found) - { - is [head] = i ; /* column j matched with row i */ - break ; /* end of augmenting path */ - } - ps [head] = Ap [j] ; /* no cheap match: start dfs for j */ - } - /* --- Depth-first-search of neighbors of j ------------------------- */ - for (p = ps [head] ; p < Ap [j+1] ; p++) - { - i = Ai [p] ; /* consider row i */ - if (w [jmatch [i]] == k) continue ; /* skip jmatch [i] if marked */ - ps [head] = p + 1 ; /* pause dfs of node j */ - is [head] = i ; /* i will be matched with j if found */ - js [++head] = jmatch [i] ; /* start dfs at column jmatch [i] */ - break ; - } - if (p == Ap [j+1]) head-- ; /* node j is done; pop from stack */ - } /* augment the match if path found: */ - if (found) for (p = head ; p >= 0 ; p--) jmatch [is [p]] = js [p] ; -} - -/* find a maximum transveral */ -int *cs_maxtrans (const cs *A) /* returns jmatch [0..m-1]; imatch [0..n-1] */ -{ - int i, j, k, n, m, p, n2 = 0, m2 = 0, *Ap, *jimatch, *w, *cheap, *js, *is, - *ps, *Ai, *Cp, *jmatch, *imatch ; - cs *C ; - if (!A) return (NULL) ; /* check inputs */ - n = A->n ; m = A->m ; Ap = A->p ; Ai = A->i ; - w = jimatch = cs_calloc (m+n, sizeof (int)) ; /* allocate result */ - if (!jimatch) return (NULL) ; - for (j = 0 ; j < n ; j++) /* count non-empty rows and columns */ - { - n2 += (Ap [j] < Ap [j+1]) ; - for (p = Ap [j] ; p < Ap [j+1] ; p++) w [Ai [p]] = 1 ; - } - for (i = 0 ; i < m ; i++) m2 += w [i] ; - C = (m2 < n2) ? cs_transpose (A,0) : ((cs *) A) ; /* transpose if needed */ - if (!C) return (cs_idone (jimatch, (m2 < n2) ? C : NULL, NULL, 0)) ; - n = C->n ; m = C->m ; Cp = C->p ; - jmatch = (m2 < n2) ? jimatch + n : jimatch ; - imatch = (m2 < n2) ? jimatch : jimatch + m ; - w = cs_malloc (5*n, sizeof (int)) ; /* allocate workspace */ - if (!w) return (cs_idone (jimatch, (m2 < n2) ? C : NULL, w, 0)) ; - cheap = w + n ; js = w + 2*n ; is = w + 3*n ; ps = w + 4*n ; - for (j = 0 ; j < n ; j++) cheap [j] = Cp [j] ; /* for cheap assignment */ - for (j = 0 ; j < n ; j++) w [j] = -1 ; /* all columns unflagged */ - for (i = 0 ; i < m ; i++) jmatch [i] = -1 ; /* nothing matched yet */ - for (k = 0 ; k < n ; k++) cs_augment (k, C, jmatch, cheap, w, js, is, ps) ; - for (j = 0 ; j < n ; j++) imatch [j] = -1 ; /* find row match */ - for (i = 0 ; i < m ; i++) if (jmatch [i] >= 0) imatch [jmatch [i]] = i ; - return (cs_idone (jimatch, (m2 < n2) ? C : NULL, w, 1)) ; -} - -/* C = A*B */ -cs *cs_multiply (const cs *A, const cs *B) -{ - int p, j, nz = 0, anz, *Cp, *Ci, *Bp, m, n, bnz, *w, values, *Bi ; - double *x, *Bx, *Cx ; - cs *C ; - if (!A || !B) return (NULL) ; /* check inputs */ - m = A->m ; anz = A->p [A->n] ; - n = B->n ; Bp = B->p ; Bi = B->i ; Bx = B->x ; bnz = Bp [n] ; - w = cs_calloc (m, sizeof (int)) ; - values = (A->x != NULL) && (Bx != NULL) ; - x = values ? cs_malloc (m, sizeof (double)) : NULL ; - C = cs_spalloc (m, n, anz + bnz, values, 0) ; - if (!C || !w || (values && !x)) return (cs_done (C, w, x, 0)) ; - Cp = C->p ; - for (j = 0 ; j < n ; j++) - { - if (nz + m > C->nzmax && !cs_sprealloc (C, 2*(C->nzmax)+m)) - { - return (cs_done (C, w, x, 0)) ; /* out of memory */ - } - Ci = C->i ; Cx = C->x ; /* C may have been reallocated */ - Cp [j] = nz ; /* column j of C starts here */ - for (p = Bp [j] ; p < Bp [j+1] ; p++) - { - nz = cs_scatter (A, Bi [p], Bx ? Bx [p] : 1, w, x, j+1, C, nz) ; - } - if (values) for (p = Cp [j] ; p < nz ; p++) Cx [p] = x [Ci [p]] ; - } - Cp [n] = nz ; /* finalize the last column of C */ - cs_sprealloc (C, 0) ; /* remove extra space from C */ - return (cs_done (C, w, x, 1)) ; /* success; free workspace, return C */ -} - -/* 1-norm of a sparse matrix = max (sum (abs (A))), largest column sum */ -double cs_norm (const cs *A) -{ - int p, j, n, *Ap ; - double *Ax, norm = 0, s ; - if (!A || !A->x) return (-1) ; /* check inputs */ - n = A->n ; Ap = A->p ; Ax = A->x ; - for (j = 0 ; j < n ; j++) - { - for (s = 0, p = Ap [j] ; p < Ap [j+1] ; p++) s += fabs (Ax [p]) ; - norm = CS_MAX (norm, s) ; - } - return (norm) ; -} - -/* C = A(P,Q) where P and Q are permutations of 0..m-1 and 0..n-1. */ -cs *cs_permute (const cs *A, const int *Pinv, const int *Q, int values) -{ - int p, j, k, nz = 0, m, n, *Ap, *Ai, *Cp, *Ci ; - double *Cx, *Ax ; - cs *C ; - if (!A) return (NULL) ; /* check inputs */ - m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; - C = cs_spalloc (m, n, Ap [n], values && Ax != NULL, 0) ; - if (!C) return (cs_done (C, NULL, NULL, 0)) ; /* out of memory */ - Cp = C->p ; Ci = C->i ; Cx = C->x ; - for (k = 0 ; k < n ; k++) - { - Cp [k] = nz ; /* column k of C is column Q[k] of A */ - j = Q ? (Q [k]) : k ; - for (p = Ap [j] ; p < Ap [j+1] ; p++) - { - if (Cx) Cx [nz] = Ax [p] ; /* row i of A is row Pinv[i] of C */ - Ci [nz++] = Pinv ? (Pinv [Ai [p]]) : Ai [p] ; - } - } - Cp [n] = nz ; /* finalize the last column of C */ - return (cs_done (C, NULL, NULL, 1)) ; -} - -/* Pinv = P', or P = Pinv' */ -int *cs_pinv (int const *P, int n) -{ - int k, *Pinv ; - if (!P) return (NULL) ; /* P = NULL denotes identity */ - Pinv = cs_malloc (n, sizeof (int)) ; /* allocate resuult */ - if (!Pinv) return (NULL) ; /* out of memory */ - for (k = 0 ; k < n ; k++) Pinv [P [k]] = k ;/* invert the permutation */ - return (Pinv) ; /* return result */ -} - -/* post order a forest */ -int *cs_post (int n, const int *parent) -{ - int j, k = 0, *post, *w, *head, *next, *stack ; - if (!parent) return (NULL) ; /* check inputs */ - post = cs_malloc (n, sizeof (int)) ; /* allocate result */ - w = cs_malloc (3*n, sizeof (int)) ; /* 3*n workspace */ - head = w ; next = w + n ; stack = w + 2*n ; - if (!w || !post) return (cs_idone (post, NULL, w, 0)) ; - for (j = 0 ; j < n ; j++) head [j] = -1 ; /* empty link lists */ - for (j = n-1 ; j >= 0 ; j--) /* traverse nodes in reverse order*/ - { - if (parent [j] == -1) continue ; /* j is a root */ - next [j] = head [parent [j]] ; /* add j to list of its parent */ - head [parent [j]] = j ; - } - for (j = 0 ; j < n ; j++) - { - if (parent [j] != -1) continue ; /* skip j if it is not a root */ - k = cs_tdfs (j, k, head, next, post, stack) ; - } - return (cs_idone (post, NULL, w, 1)) ; /* success; free w, return post */ -} - -/* print a sparse matrix */ -int cs_print (const cs *A, int brief) -{ - int p, j, m, n, nzmax, nz, *Ap, *Ai ; - double *Ax ; - if (!A) { printf ("(null)\n") ; return (0) ; } - m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; - nzmax = A->nzmax ; nz = A->nz ; - printf ("CSparse Version %d.%d.%d, %s. %s\n", CS_VER, CS_SUBVER, - CS_SUBSUB, CS_DATE, CS_COPYRIGHT) ; - if (nz < 0) - { - printf ("%d-by-%d, nzmax: %d nnz: %d, 1-norm: %g\n", m, n, nzmax, - Ap [n], cs_norm (A)) ; - for (j = 0 ; j < n ; j++) - { - printf (" col %d : locations %d to %d\n", j, Ap [j], Ap [j+1]-1); - for (p = Ap [j] ; p < Ap [j+1] ; p++) - { - printf (" %d : %g\n", Ai [p], Ax ? Ax [p] : 1) ; - if (brief && p > 20) { printf (" ...\n") ; return (1) ; } - } - } - } - else - { - printf ("triplet: %d-by-%d, nzmax: %d nnz: %d\n", m, n, nzmax, nz) ; - for (p = 0 ; p < nz ; p++) - { - printf (" %d %d : %g\n", Ai [p], Ap [p], Ax ? Ax [p] : 1) ; - if (brief && p > 20) { printf (" ...\n") ; return (1) ; } - } - } - return (1) ; -} - -/* x = b(P), for dense vectors x and b; P=NULL denotes identity */ -int cs_pvec (int n, const int *P, const double *b, double *x) -{ - int k ; - if (!x || !b) return (0) ; /* check inputs */ - for (k = 0 ; k < n ; k++) x [k] = b [P ? P [k] : k] ; - return (1) ; -} - -/* sparse QR factorization [V,beta,p,R] = qr (A) */ -csn *cs_qr (const cs *A, const css *S) -{ - double *Rx, *Vx, *Ax, *Beta, *x ; - int i, k, p, m, n, vnz, p1, top, m2, len, col, rnz, *s, *leftmost, *Ap, - *Ai, *parent, *Rp, *Ri, *Vp, *Vi, *w, *Pinv, *Q ; - cs *R, *V ; - csn *N ; - if (!A || !S || !S->parent || !S->Pinv) return (NULL) ; /* check inputs */ - m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; - Q = S->Q ; parent = S->parent ; Pinv = S->Pinv ; m2 = S->m2 ; - vnz = S->lnz ; rnz = S->unz ; - leftmost = Pinv + m + n ; - w = cs_malloc (m2+n, sizeof (int)) ; - x = cs_malloc (m2, sizeof (double)) ; - N = cs_calloc (1, sizeof (csn)) ; - if (!w || !x || !N) return (cs_ndone (N, NULL, w, x, 0)) ; - s = w + m2 ; /* size n */ - for (k = 0 ; k < m2 ; k++) x [k] = 0 ; /* clear workspace x */ - N->L = V = cs_spalloc (m2, n, vnz, 1, 0) ; /* allocate V */ - N->U = R = cs_spalloc (m2, n, rnz, 1, 0) ; /* allocate R, m2-by-n */ - N->B = Beta = cs_malloc (n, sizeof (double)) ; - if (!R || !V || !Beta) return (cs_ndone (N, NULL, w, x, 0)) ; - Rp = R->p ; Ri = R->i ; Rx = R->x ; - Vp = V->p ; Vi = V->i ; Vx = V->x ; - for (i = 0 ; i < m2 ; i++) w [i] = -1 ; /* clear w, to mark nodes */ - rnz = 0 ; vnz = 0 ; - for (k = 0 ; k < n ; k++) /* compute V and R */ - { - Rp [k] = rnz ; /* R(:,k) starts here */ - Vp [k] = p1 = vnz ; /* V(:,k) starts here */ - w [k] = k ; /* add V(k,k) to pattern of V */ - Vi [vnz++] = k ; - top = n ; - col = Q ? Q [k] : k ; - for (p = Ap [col] ; p < Ap [col+1] ; p++) /* find R(:,k) pattern */ - { - i = leftmost [Ai [p]] ; /* i = min(find(A(i,Q))) */ - for (len = 0 ; w [i] != k ; i = parent [i]) /* traverse up to k */ - { - s [len++] = i ; - w [i] = k ; - } - while (len > 0) s [--top] = s [--len] ; /* push path on stack */ - i = Pinv [Ai [p]] ; /* i = permuted row of A(:,col) */ - x [i] = Ax [p] ; /* x (i) = A(.,col) */ - if (i > k && w [i] < k) /* pattern of V(:,k) = x (k+1:m) */ - { - Vi [vnz++] = i ; /* add i to pattern of V(:,k) */ - w [i] = k ; - } - } - for (p = top ; p < n ; p++) /* for each i in pattern of R(:,k) */ - { - i = s [p] ; /* R(i,k) is nonzero */ - cs_happly (V, i, Beta [i], x) ; /* apply (V(i),Beta(i)) to x */ - Ri [rnz] = i ; /* R(i,k) = x(i) */ - Rx [rnz++] = x [i] ; - x [i] = 0 ; - if (parent [i] == k) vnz = cs_scatter (V, i, 0, w, NULL, k, V, vnz); - } - for (p = p1 ; p < vnz ; p++) /* gather V(:,k) = x */ - { - Vx [p] = x [Vi [p]] ; - x [Vi [p]] = 0 ; - } - Ri [rnz] = k ; /* R(k,k) = norm (x) */ - Rx [rnz++] = cs_house (Vx+p1, Beta+k, vnz-p1) ; /* [v,beta]=house(x) */ - } - Rp [n] = rnz ; /* finalize R */ - Vp [n] = vnz ; /* finalize V */ - return (cs_ndone (N, NULL, w, x, 1)) ; /* success */ -} - -/* x=A\b where A can be rectangular; b overwritten with solution */ -int cs_qrsol (const cs *A, double *b, int order) -{ - double *x ; - css *S ; - csn *N ; - cs *AT = NULL ; - int k, m, n, ok ; - if (!A || !b) return (0) ; /* check inputs */ - n = A->n ; - m = A->m ; - if (m >= n) - { - S = cs_sqr (A, order, 1) ; /* ordering and symbolic analysis */ - N = cs_qr (A, S) ; /* numeric QR factorization */ - x = cs_calloc (S ? S->m2 : 1, sizeof (double)) ; - ok = (S && N && x) ; - if (ok) - { - cs_ipvec (m, S->Pinv, b, x) ; /* x(0:m-1) = P*b(0:m-1) */ - for (k = 0 ; k < n ; k++) /* apply Householder refl. to x */ - { - cs_happly (N->L, k, N->B [k], x) ; - } - cs_usolve (N->U, x) ; /* x = R\x */ - cs_ipvec (n, S->Q, x, b) ; /* b(0:n-1) = Q*x (permutation) */ - } - } - else - { - AT = cs_transpose (A, 1) ; /* Ax=b is underdetermined */ - S = cs_sqr (AT, order, 1) ; /* ordering and symbolic analysis */ - N = cs_qr (AT, S) ; /* numeric QR factorization of A' */ - x = cs_calloc (S ? S->m2 : 1, sizeof (double)) ; - ok = (AT && S && N && x) ; - if (ok) - { - cs_pvec (m, S->Q, b, x) ; /* x(0:m-1) = Q'*b (permutation) */ - cs_utsolve (N->U, x) ; /* x = R'\x */ - for (k = m-1 ; k >= 0 ; k--) /* apply Householder refl. to x */ - { - cs_happly (N->L, k, N->B [k], x) ; - } - cs_pvec (n, S->Pinv, x, b) ; /* b (0:n-1) = P'*x */ - } - } - cs_free (x) ; - cs_sfree (S) ; - cs_nfree (N) ; - cs_spfree (AT) ; - return (ok) ; -} - -/* xi [top...n-1] = nodes reachable from graph of L*P' via nodes in B(:,k). - * xi [n...2n-1] used as workspace */ -int cs_reach (cs *L, const cs *B, int k, int *xi, const int *Pinv) -{ - int p, n, top, *Bp, *Bi, *Lp ; - if (!L || !B || !xi) return (-1) ; - n = L->n ; Bp = B->p ; Bi = B->i ; Lp = L->p ; - top = n ; - for (p = Bp [k] ; p < Bp [k+1] ; p++) - { - if (!CS_MARKED (Lp, Bi [p])) /* start a dfs at unmarked node i */ - { - top = cs_dfs (Bi [p], L, top, xi, xi+n, Pinv) ; - } - } - for (p = top ; p < n ; p++) CS_MARK (Lp, xi [p]) ; /* restore L */ - return (top) ; -} - -/* x = x + beta * A(:,j), where x is a dense vector and A(:,j) is sparse */ -int cs_scatter (const cs *A, int j, double beta, int *w, double *x, int mark, - cs *C, int nz) -{ - int i, p, *Ap, *Ai, *Ci ; - double *Ax ; - if (!A || !w || !C) return (-1) ; /* ensure inputs are valid */ - Ap = A->p ; Ai = A->i ; Ax = A->x ; Ci = C->i ; - for (p = Ap [j] ; p < Ap [j+1] ; p++) - { - i = Ai [p] ; /* A(i,j) is nonzero */ - if (w [i] < mark) - { - w [i] = mark ; /* i is new entry in column j */ - Ci [nz++] = i ; /* add i to pattern of C(:,j) */ - if (x) x [i] = beta * Ax [p] ; /* x(i) = beta*A(i,j) */ - } - else if (x) x [i] += beta * Ax [p] ; /* i exists in C(:,j) already */ - } - return (nz) ; -} - -/* find the strongly connected components of a square matrix */ -csd *cs_scc (cs *A) /* matrix A temporarily modified, then restored */ -{ - int n, i, k, b = 0, top, *xi, *pstack, *P, *R, *Ap, *ATp ; - cs *AT ; - csd *D ; - if (!A) return (NULL) ; - n = A->n ; Ap = A->p ; - D = cs_dalloc (n, 0) ; - AT = cs_transpose (A, 0) ; /* AT = A' */ - xi = cs_malloc (2*n, sizeof (int)) ; /* allocate workspace */ - pstack = xi + n ; - if (!D || !AT || !xi) return (cs_ddone (D, AT, xi, 0)) ; - P = D->P ; R = D->R ; ATp = AT->p ; - top = n ; - for (i = 0 ; i < n ; i++) /* first dfs(A) to find finish times (xi) */ - { - if (!CS_MARKED (Ap,i)) top = cs_dfs (i, A, top, xi, pstack, NULL) ; - } - for (i = 0 ; i < n ; i++) CS_MARK (Ap, i) ; /* restore A; unmark all nodes*/ - top = n ; - b = n ; - for (k = 0 ; k < n ; k++) /* dfs(A') to find strongly connnected comp. */ - { - i = xi [k] ; /* get i in reverse order of finish times */ - if (CS_MARKED (ATp,i)) continue ; /* skip node i if already ordered */ - R [b--] = top ; /* node i is the start of a component in P */ - top = cs_dfs (i, AT, top, P, pstack, NULL) ; - } - R [b] = 0 ; /* first block starts at zero; shift R up */ - for (k = b ; k <= n ; k++) R [k-b] = R [k] ; - D->nb = R [n+1] = b = n-b ; /* b = # of strongly connected components */ - return (cs_ddone (D, AT, xi, 1)) ; -} - -/* ordering and symbolic analysis for a Cholesky factorization */ -css *cs_schol (const cs *A, int order) -{ - int n, *c, *post, *P ; - cs *C ; - css *S ; - if (!A) return (NULL) ; /* check inputs */ - n = A->n ; - S = cs_calloc (1, sizeof (css)) ; /* allocate symbolic analysis */ - if (!S) return (NULL) ; /* out of memory */ - P = cs_amd (A, order) ; /* P = amd(A+A'), or natural */ - S->Pinv = cs_pinv (P, n) ; /* find inverse permutation */ - cs_free (P) ; - if (order >= 0 && !S->Pinv) return (cs_sfree (S)) ; - C = cs_symperm (A, S->Pinv, 0) ; /* C = spones(triu(A(P,P))) */ - S->parent = cs_etree (C, 0) ; /* find etree of C */ - post = cs_post (n, S->parent) ; /* postorder the etree */ - c = cs_counts (C, S->parent, post, 0) ; /* find column counts of chol(C) */ - cs_free (post) ; - cs_spfree (C) ; - S->cp = cs_malloc (n+1, sizeof (int)) ; /* find column pointers for L */ - S->unz = S->lnz = cs_cumsum (S->cp, c, n) ; - cs_free (c) ; - return ((S->lnz >= 0) ? S : cs_sfree (S)) ; -} - -/* solve Lx=b(:,k), leaving pattern in xi[top..n-1], values scattered in x. */ -int cs_splsolve (cs *L, const cs *B, int k, int *xi, double *x, const int *Pinv) -{ - int j, jnew, p, px, top, n, *Lp, *Li, *Bp, *Bi ; - double *Lx, *Bx ; - if (!L || !B || !xi || !x) return (-1) ; - Lp = L->p ; Li = L->i ; Lx = L->x ; n = L->n ; - Bp = B->p ; Bi = B->i ; Bx = B->x ; - top = cs_reach (L, B, k, xi, Pinv) ; /* xi[top..n-1]=Reach(B(:,k)) */ - for (p = top ; p < n ; p++) x [xi [p]] = 0 ;/* clear x */ - for (p = Bp [k] ; p < Bp [k+1] ; p++) x [Bi [p]] = Bx [p] ; /* scatter B */ - for (px = top ; px < n ; px++) - { - j = xi [px] ; /* x(j) is nonzero */ - jnew = Pinv ? (Pinv [j]) : j ; /* j is column jnew of L */ - if (jnew < 0) continue ; /* column jnew is empty */ - for (p = Lp [jnew]+1 ; p < Lp [jnew+1] ; p++) - { - x [Li [p]] -= Lx [p] * x [j] ; /* x(i) -= L(i,j) * x(j) */ - } - } - return (top) ; /* return top of stack */ -} - -/* compute vnz, Pinv, leftmost, m2 from A and parent */ -static int *cs_vcount (const cs *A, const int *parent, int *m2, int *vnz) -{ - int i, k, p, pa, n = A->n, m = A->m, *Ap = A->p, *Ai = A->i ; - int *Pinv = cs_malloc (2*m+n, sizeof (int)), *leftmost = Pinv + m + n ; - int *w = cs_malloc (m+3*n, sizeof (int)) ; - int *next = w, *head = w + m, *tail = w + m + n, *nque = w + m + 2*n ; - if (!Pinv || !w) return (cs_idone (Pinv, NULL, w, 0)) ; - for (k = 0 ; k < n ; k++) head [k] = -1 ; /* queue k is empty */ - for (k = 0 ; k < n ; k++) tail [k] = -1 ; - for (k = 0 ; k < n ; k++) nque [k] = 0 ; - for (i = 0 ; i < m ; i++) leftmost [i] = -1 ; - for (k = n-1 ; k >= 0 ; k--) - { - for (p = Ap [k] ; p < Ap [k+1] ; p++) - { - leftmost [Ai [p]] = k ; /* leftmost[i] = min(find(A(i,:)))*/ - } - } - for (i = m-1 ; i >= 0 ; i--) /* scan rows in reverse order */ - { - Pinv [i] = -1 ; /* row i is not yet ordered */ - k = leftmost [i] ; - if (k == -1) continue ; /* row i is empty */ - if (nque [k]++ == 0) tail [k] = i ; /* first row in queue k */ - next [i] = head [k] ; /* put i at head of queue k */ - head [k] = i ; - } - (*vnz) = 0 ; - (*m2) = m ; - for (k = 0 ; k < n ; k++) /* find row permutation and nnz(V)*/ - { - i = head [k] ; /* remove row i from queue k */ - (*vnz)++ ; /* count V(k,k) as nonzero */ - if (i < 0) i = (*m2)++ ; /* add a fictitious row */ - Pinv [i] = k ; /* associate row i with V(:,k) */ - if (--nque [k] <= 0) continue ; /* skip if V(k+1:m,k) is empty */ - (*vnz) += nque [k] ; /* nque [k] = nnz (V(k+1:m,k)) */ - if ((pa = parent [k]) != -1) /* move all rows to parent of k */ - { - if (nque [pa] == 0) tail [pa] = tail [k] ; - next [tail [k]] = head [pa] ; - head [pa] = next [i] ; - nque [pa] += nque [k] ; - } - } - for (i = 0 ; i < m ; i++) if (Pinv [i] < 0) Pinv [i] = k++ ; - return (cs_idone (Pinv, NULL, w, 1)) ; -} - -/* symbolic analysis for QR or LU */ -css *cs_sqr (const cs *A, int order, int qr) -{ - int n, k, ok = 1, *post ; - css *S ; - if (!A) return (NULL) ; /* check inputs */ - n = A->n ; - S = cs_calloc (1, sizeof (css)) ; /* allocate symbolic analysis */ - if (!S) return (NULL) ; /* out of memory */ - S->Q = cs_amd (A, order) ; /* fill-reducing ordering */ - if (order >= 0 && !S->Q) return (cs_sfree (S)) ; - if (qr) /* QR symbolic analysis */ - { - cs *C = (order >= 0) ? cs_permute (A, NULL, S->Q, 0) : ((cs *) A) ; - S->parent = cs_etree (C, 1) ; /* etree of C'*C, where C=A(:,Q) */ - post = cs_post (n, S->parent) ; - S->cp = cs_counts (C, S->parent, post, 1) ; /* col counts chol(C'*C) */ - cs_free (post) ; - ok = C && S->parent && S->cp ; - if (ok) S->Pinv = cs_vcount (C, S->parent, &(S->m2), &(S->lnz)) ; - ok = ok && S->Pinv ; - if (ok) for (S->unz = 0, k = 0 ; k < n ; k++) S->unz += S->cp [k] ; - if (order >= 0) cs_spfree (C) ; - } - else - { - S->unz = 4*(A->p [n]) + n ; /* for LU factorization only, */ - S->lnz = S->unz ; /* guess nnz(L) and nnz(U) */ - } - return (ok ? S : cs_sfree (S)) ; -} - -/* C = A(p,p) where A and C are symmetric the upper part stored, Pinv not P */ -cs *cs_symperm (const cs *A, const int *Pinv, int values) -{ - int i, j, p, q, i2, j2, n, *Ap, *Ai, *Cp, *Ci, *w ; - double *Cx, *Ax ; - cs *C ; - if (!A) return (NULL) ; - n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; - C = cs_spalloc (n, n, Ap [n], values && (Ax != NULL), 0) ; - w = cs_calloc (n, sizeof (int)) ; - if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ - Cp = C->p ; Ci = C->i ; Cx = C->x ; - for (j = 0 ; j < n ; j++) /* count entries in each column of C */ - { - j2 = Pinv ? Pinv [j] : j ; /* column j of A is column j2 of C */ - for (p = Ap [j] ; p < Ap [j+1] ; p++) - { - i = Ai [p] ; - if (i > j) continue ; /* skip lower triangular part of A */ - i2 = Pinv ? Pinv [i] : i ; /* row i of A is row i2 of C */ - w [CS_MAX (i2, j2)]++ ; /* column count of C */ - } - } - cs_cumsum (Cp, w, n) ; /* compute column pointers of C */ - for (j = 0 ; j < n ; j++) - { - j2 = Pinv ? Pinv [j] : j ; /* column j of A is column j2 of C */ - for (p = Ap [j] ; p < Ap [j+1] ; p++) - { - i = Ai [p] ; - if (i > j) continue ; /* skip lower triangular part of A*/ - i2 = Pinv ? Pinv [i] : i ; /* row i of A is row i2 of C */ - Ci [q = w [CS_MAX (i2, j2)]++] = CS_MIN (i2, j2) ; - if (Cx) Cx [q] = Ax [p] ; - } - } - return (cs_done (C, w, NULL, 1)) ; /* success; free workspace, return C */ -} - -/* depth-first search and postorder of a tree rooted at node j */ -int cs_tdfs (int j, int k, int *head, const int *next, int *post, int *stack) -{ - int i, p, top = 0 ; - if (!head || !next || !post || !stack) return (-1) ; /* check inputs */ - stack [0] = j ; /* place j on the stack */ - while (top >= 0) /* while (stack is not empty) */ - { - p = stack [top] ; /* p = top of stack */ - i = head [p] ; /* i = youngest child of p */ - if (i == -1) - { - top-- ; /* p has no unordered children left */ - post [k++] = p ; /* node p is the kth postordered node */ - } - else - { - head [p] = next [i] ; /* remove i from children of p */ - stack [++top] = i ; /* start dfs on child node i */ - } - } - return (k) ; -} - -/* C = A' */ -cs *cs_transpose (const cs *A, int values) -{ - int p, q, j, *Cp, *Ci, n, m, *Ap, *Ai, *w ; - double *Cx, *Ax ; - cs *C ; - if (!A) return (NULL) ; - m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; - C = cs_spalloc (n, m, Ap [n], values && Ax, 0) ; /* allocate result */ - w = cs_calloc (m, sizeof (int)) ; - if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ - Cp = C->p ; Ci = C->i ; Cx = C->x ; - for (p = 0 ; p < Ap [n] ; p++) w [Ai [p]]++ ; /* row counts */ - cs_cumsum (Cp, w, m) ; /* row pointers */ - for (j = 0 ; j < n ; j++) - { - for (p = Ap [j] ; p < Ap [j+1] ; p++) - { - Ci [q = w [Ai [p]]++] = j ; /* place A(i,j) as entry C(j,i) */ - if (Cx) Cx [q] = Ax [p] ; - } - } - return (cs_done (C, w, NULL, 1)) ; /* success; free w and return C */ -} - -/* C = compressed-column form of a triplet matrix T */ -cs *cs_triplet (const cs *T) -{ - int m, n, nz, p, k, *Cp, *Ci, *w, *Ti, *Tj ; - double *Cx, *Tx ; - cs *C ; - if (!T) return (NULL) ; /* check inputs */ - m = T->m ; n = T->n ; Ti = T->i ; Tj = T->p ; Tx = T->x ; nz = T->nz ; - C = cs_spalloc (m, n, nz, Tx != NULL, 0) ; /* allocate result */ - w = cs_calloc (n, sizeof (int)) ; /* get workspace */ - if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ - Cp = C->p ; Ci = C->i ; Cx = C->x ; - for (k = 0 ; k < nz ; k++) w [Tj [k]]++ ; /* column counts */ - cs_cumsum (Cp, w, n) ; /* column pointers */ - for (k = 0 ; k < nz ; k++) - { - Ci [p = w [Tj [k]]++] = Ti [k] ; /* A(i,j) is the pth entry in C */ - if (Cx) Cx [p] = Tx [k] ; - } - return (cs_done (C, w, NULL, 1)) ; /* success; free w and return C */ -} - -/* sparse Cholesky update/downdate, L*L' + sigma*w*w' (sigma = +1 or -1) */ -int cs_updown (cs *L, int sigma, const cs *C, const int *parent) -{ - int p, f, j, n, *Lp, *Li, *Cp, *Ci ; - double *Lx, *Cx, alpha, beta = 1, delta, gamma, w1, w2, *w, beta2 = 1 ; - if (!L || !C || !parent) return (0) ; - Lp = L->p ; Li = L->i ; Lx = L->x ; n = L->n ; - Cp = C->p ; Ci = C->i ; Cx = C->x ; - if ((p = Cp [0]) >= Cp [1]) return (1) ; /* return if C empty */ - w = cs_malloc (n, sizeof (double)) ; - if (!w) return (0) ; - f = Ci [p] ; - for ( ; p < Cp [1] ; p++) f = CS_MIN (f, Ci [p]) ; /* f = min (find (C)) */ - for (j = f ; j != -1 ; j = parent [j]) w [j] = 0 ; /* clear workspace w */ - for (p = Cp [0] ; p < Cp [1] ; p++) w [Ci [p]] = Cx [p] ; /* w = C */ - for (j = f ; j != -1 ; j = parent [j]) /* walk path f up to root */ - { - p = Lp [j] ; - alpha = w [j] / Lx [p] ; /* alpha = w(j) / L(j,j) */ - beta2 = beta*beta + sigma*alpha*alpha ; - if (beta2 <= 0) break ; /* not positive definite */ - beta2 = sqrt (beta2) ; - delta = (sigma > 0) ? (beta / beta2) : (beta2 / beta) ; - gamma = sigma * alpha / (beta2 * beta) ; - Lx [p] = delta * Lx [p] + ((sigma > 0) ? (gamma * w [j]) : 0) ; - beta = beta2 ; - for (p++ ; p < Lp [j+1] ; p++) - { - w1 = w [Li [p]] ; - w [Li [p]] = w2 = w1 - alpha * Lx [p] ; - Lx [p] = delta * Lx [p] + gamma * ((sigma > 0) ? w1 : w2) ; - } - } - cs_free (w) ; - return (beta2 > 0) ; -} - -/* solve Ux=b where x and b are dense. x=b on input, solution on output. */ -int cs_usolve (const cs *U, double *x) -{ - int p, j, n, *Up, *Ui ; - double *Ux ; - if (!U || !x) return (0) ; /* check inputs */ - n = U->n ; Up = U->p ; Ui = U->i ; Ux = U->x ; - for (j = n-1 ; j >= 0 ; j--) - { - x [j] /= Ux [Up [j+1]-1] ; - for (p = Up [j] ; p < Up [j+1]-1 ; p++) - { - x [Ui [p]] -= Ux [p] * x [j] ; - } - } - return (1) ; -} - -/* allocate a sparse matrix (triplet form or compressed-column form) */ -cs *cs_spalloc (int m, int n, int nzmax, int values, int triplet) -{ - cs *A = cs_calloc (1, sizeof (cs)) ; /* allocate the cs struct */ - if (!A) return (NULL) ; /* out of memory */ - A->m = m ; /* define dimensions and nzmax */ - A->n = n ; - A->nzmax = nzmax = CS_MAX (nzmax, 1) ; - A->nz = triplet ? 0 : -1 ; /* allocate triplet or comp.col */ - A->p = cs_malloc (triplet ? nzmax : n+1, sizeof (int)) ; - A->i = cs_malloc (nzmax, sizeof (int)) ; - A->x = values ? cs_malloc (nzmax, sizeof (double)) : NULL ; - return ((!A->p || !A->i || (values && !A->x)) ? cs_spfree (A) : A) ; -} - -/* change the max # of entries sparse matrix */ -int cs_sprealloc (cs *A, int nzmax) -{ - int ok, oki, okj = 1, okx = 1 ; - if (!A) return (0) ; - nzmax = (nzmax <= 0) ? (A->p [A->n]) : nzmax ; - A->i = cs_realloc (A->i, nzmax, sizeof (int), &oki) ; - if (A->nz >= 0) A->p = cs_realloc (A->p, nzmax, sizeof (int), &okj) ; - if (A->x) A->x = cs_realloc (A->x, nzmax, sizeof (double), &okx) ; - ok = (oki && okj && okx) ; - if (ok) A->nzmax = nzmax ; - return (ok) ; -} - -/* free a sparse matrix */ -cs *cs_spfree (cs *A) -{ - if (!A) return (NULL) ; /* do nothing if A already NULL */ - cs_free (A->p) ; - cs_free (A->i) ; - cs_free (A->x) ; - return (cs_free (A)) ; /* free the cs struct and return NULL */ -} - -/* free a numeric factorization */ -csn *cs_nfree (csn *N) -{ - if (!N) return (NULL) ; /* do nothing if N already NULL */ - cs_spfree (N->L) ; - cs_spfree (N->U) ; - cs_free (N->Pinv) ; - cs_free (N->B) ; - return (cs_free (N)) ; /* free the csn struct and return NULL */ -} - -/* free a symbolic factorization */ -css *cs_sfree (css *S) -{ - if (!S) return (NULL) ; /* do nothing if S already NULL */ - cs_free (S->Pinv) ; - cs_free (S->Q) ; - cs_free (S->parent) ; - cs_free (S->cp) ; - return (cs_free (S)) ; /* free the css struct and return NULL */ -} - -/* allocate a cs_dmperm or cs_scc result */ -csd *cs_dalloc (int m, int n) -{ - csd *D ; - D = cs_calloc (1, sizeof (csd)) ; - if (!D) return (NULL) ; - D->P = cs_malloc (m, sizeof (int)) ; - D->R = cs_malloc (m+6, sizeof (int)) ; - D->Q = cs_malloc (n, sizeof (int)) ; - D->S = cs_malloc (n+6, sizeof (int)) ; - return ((!D->P || !D->R || !D->Q || !D->S) ? cs_dfree (D) : D) ; -} - -/* free a cs_dmperm or cs_scc result */ -csd *cs_dfree (csd *D) -{ - if (!D) return (NULL) ; /* do nothing if D already NULL */ - cs_free (D->P) ; - cs_free (D->Q) ; - cs_free (D->R) ; - cs_free (D->S) ; - return (cs_free (D)) ; -} - -/* free workspace and return a sparse matrix result */ -cs *cs_done (cs *C, void *w, void *x, int ok) -{ - cs_free (w) ; /* free workspace */ - cs_free (x) ; - return (ok ? C : cs_spfree (C)) ; /* return result if OK, else free it */ -} - -/* free workspace and return int array result */ -int *cs_idone (int *p, cs *C, void *w, int ok) -{ - cs_spfree (C) ; /* free temporary matrix */ - cs_free (w) ; /* free workspace */ - return (ok ? p : cs_free (p)) ; /* return result if OK, else free it */ -} - -/* free workspace and return a numeric factorization (Cholesky, LU, or QR) */ -csn *cs_ndone (csn *N, cs *C, void *w, void *x, int ok) -{ - cs_spfree (C) ; /* free temporary matrix */ - cs_free (w) ; /* free workspace */ - cs_free (x) ; - return (ok ? N : cs_nfree (N)) ; /* return result if OK, else free it */ -} - -/* free workspace and return a csd result */ -csd *cs_ddone (csd *D, cs *C, void *w, int ok) -{ - cs_spfree (C) ; /* free temporary matrix */ - cs_free (w) ; /* free workspace */ - return (ok ? D : cs_dfree (D)) ; /* return result if OK, else free it */ -} - -/* solve U'x=b where x and b are dense. x=b on input, solution on output. */ -int cs_utsolve (const cs *U, double *x) -{ - int p, j, n, *Up, *Ui ; - double *Ux ; - if (!U || !x) return (0) ; /* check inputs */ - n = U->n ; Up = U->p ; Ui = U->i ; Ux = U->x ; - for (j = 0 ; j < n ; j++) - { - for (p = Up [j] ; p < Up [j+1]-1 ; p++) - { - x [j] -= Ux [p] * x [Ui [p]] ; - } - x [j] /= Ux [p] ; - } - return (1) ; -} diff --git a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/csparse.h b/Sofa/Component/LinearSolver/Direct/extlibs/csparse/csparse.h deleted file mode 100644 index 1c0b8e514a30..000000000000 --- a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/csparse.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef _CS_H -#define _CS_H - -#ifdef MATLAB_MEX_FILE -#include "mex.h" -#endif -#define CS_VER 1 /* CSparse Version 1.2.0 */ -#define CS_SUBVER 2 -#define CS_SUBSUB 0 -#define CS_DATE "Mar 6, 2006" /* CSparse release date */ -#define CS_COPYRIGHT "Copyright (c) Timothy A. Davis, 2006" - -#if defined(__cplusplus) -extern "C" { -#endif - -/* --- primary CSparse routines and data structures ------------------------- */ -typedef struct cs_sparse /* matrix in compressed-column or triplet form */ -{ - int nzmax ; /* maximum number of entries */ - int m ; /* number of rows */ - int n ; /* number of columns */ - int *p ; /* column pointers (size n+1) or col indices (size nzmax) */ - int *i ; /* row indices, size nzmax */ - double *x ; /* numerical values, size nzmax */ - int nz ; /* # of entries in triplet matrix, -1 for compressed-col */ -} cs ; - -cs *cs_add (const cs *A, const cs *B, double alpha, double beta) ; -int cs_cholsol (const cs *A, double *b, int order) ; -int cs_dupl (cs *A) ; -int cs_entry (cs *T, int i, int j, double x) ; -int cs_lusol (const cs *A, double *b, int order, double tol) ; -int cs_gaxpy (const cs *A, const double *x, double *y) ; -cs *cs_multiply (const cs *A, const cs *B) ; -int cs_qrsol (const cs *A, double *b, int order) ; -cs *cs_transpose (const cs *A, int values) ; -cs *cs_triplet (const cs *T) ; -double cs_norm (const cs *A) ; -int cs_print (const cs *A, int brief) ; -cs *cs_load (FILE *f) ; -/* utilities */ -void *cs_calloc (int n, size_t size) ; -void *cs_free (void *p) ; -void *cs_realloc (void *p, int n, size_t size, int *ok) ; -cs *cs_spalloc (int m, int n, int nzmax, int values, int triplet) ; -cs *cs_spfree (cs *A) ; -int cs_sprealloc (cs *A, int nzmax) ; -void *cs_malloc (int n, size_t size) ; - -/* --- secondary CSparse routines and data structures ----------------------- */ -typedef struct cs_symbolic /* symbolic Cholesky, LU, or QR analysis */ -{ - int *Pinv ; /* inverse row perm. for QR, fill red. perm for Chol */ - int *Q ; /* fill-reducing column permutation for LU and QR */ - int *parent ; /* elimination tree for Cholesky and QR */ - int *cp ; /* column pointers for Cholesky, row counts for QR */ - int m2 ; /* # of rows for QR, after adding fictitious rows */ - int lnz ; /* # entries in L for LU or Cholesky; in V for QR */ - int unz ; /* # entries in U for LU; in R for QR */ -} css ; - -typedef struct cs_numeric /* numeric Cholesky, LU, or QR factorization */ -{ - cs *L ; /* L for LU and Cholesky, V for QR */ - cs *U ; /* U for LU, R for QR, not used for Cholesky */ - int *Pinv ; /* partial pivoting for LU */ - double *B ; /* beta [0..n-1] for QR */ -} csn ; - -typedef struct cs_dmperm_results /* cs_dmperm or cs_scc output */ -{ - int *P ; /* size m, row permutation */ - int *Q ; /* size n, column permutation */ - int *R ; /* size nb+1, block k is rows R[k] to R[k+1]-1 in A(P,Q) */ - int *S ; /* size nb+1, block k is cols S[k] to S[k+1]-1 in A(P,Q) */ - int nb ; /* # of blocks in fine dmperm decomposition */ - int rr [5] ; /* coarse row decomposition */ - int cc [5] ; /* coarse column decomposition */ -} csd ; - -int *cs_amd (const cs *A, int order) ; -csn *cs_chol (const cs *A, const css *S) ; -csd *cs_dmperm (const cs *A) ; -int cs_droptol (cs *A, double tol) ; -int cs_dropzeros (cs *A) ; -int cs_happly (const cs *V, int i, double beta, double *x) ; -int cs_ipvec (int n, const int *P, const double *b, double *x) ; -int cs_lsolve (const cs *L, double *x) ; -int cs_ltsolve (const cs *L, double *x) ; -csn *cs_lu (const cs *A, const css *S, double tol) ; -cs *cs_permute (const cs *A, const int *P, const int *Q, int values) ; -int *cs_pinv (const int *P, int n) ; -int cs_pvec (int n, const int *P, const double *b, double *x) ; -csn *cs_qr (const cs *A, const css *S) ; -css *cs_schol (const cs *A, int order) ; -css *cs_sqr (const cs *A, int order, int qr) ; -cs *cs_symperm (const cs *A, const int *Pinv, int values) ; -int cs_usolve (const cs *U, double *x) ; -int cs_utsolve (const cs *U, double *x) ; -int cs_updown (cs *L, int sigma, const cs *C, const int *parent) ; -/* utilities */ -css *cs_sfree (css *S) ; -csn *cs_nfree (csn *N) ; -csd *cs_dfree (csd *D) ; - -/* --- tertiary CSparse routines -------------------------------------------- */ -int *cs_counts (const cs *A, const int *parent, const int *post, int ata) ; -int cs_cumsum (int *p, int *c, int n) ; -int cs_dfs (int j, cs *L, int top, int *xi, int *pstack, const int *Pinv) ; -int *cs_etree (const cs *A, int ata) ; -int cs_fkeep (cs *A, int (*fkeep) (int, int, double, void *), void *other) ; -double cs_house (double *x, double *beta, int n) ; -int *cs_maxtrans (const cs *A) ; -int *cs_post (int n, const int *parent) ; -int cs_reach (cs *L, const cs *B, int k, int *xi, const int *Pinv) ; -csd *cs_scc (cs *A) ; -int cs_scatter (const cs *A, int j, double beta, int *w, double *x, int mark, - cs *C, int nz) ; -int cs_splsolve (cs *L, const cs *B, int k, int *xi, double *x, - const int *Pinv) ; -int cs_tdfs (int j, int k, int *head, const int *next, int *post, - int *stack) ; -/* utilities */ -csd *cs_dalloc (int m, int n) ; -cs *cs_done (cs *C, void *w, void *x, int ok) ; -int *cs_idone (int *p, cs *C, void *w, int ok) ; -csn *cs_ndone (csn *N, cs *C, void *w, void *x, int ok) ; -csd *cs_ddone (csd *D, cs *C, void *w, int ok) ; - -#define CS_MAX(a,b) (((a) > (b)) ? (a) : (b)) -#define CS_MIN(a,b) (((a) < (b)) ? (a) : (b)) -#define CS_FLIP(i) (-(i)-2) -#define CS_UNFLIP(i) (((i) < 0) ? CS_FLIP(i) : (i)) -#define CS_MARKED(Ap,j) (Ap [j] < 0) -#define CS_MARK(Ap,j) { Ap [j] = CS_FLIP (Ap [j]) ; } -#define CS_OVERFLOW(n,size) (n > INT_MAX / (int) size) - - -#if defined(__cplusplus) -} //extern "C" -#endif - -#endif diff --git a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/ldl.c b/Sofa/Component/LinearSolver/Direct/extlibs/csparse/ldl.c deleted file mode 100644 index a9b35c846efa..000000000000 --- a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/ldl.c +++ /dev/null @@ -1,507 +0,0 @@ -/* ========================================================================== */ -/* === ldl.c: sparse LDL' factorization and solve package =================== */ -/* ========================================================================== */ - -/* LDL: a simple set of routines for sparse LDL' factorization. These routines - * are not terrifically fast (they do not use dense matrix kernels), but the - * code is very short. The purpose is to illustrate the algorithms in a very - * concise manner, primarily for educational purposes. Although the code is - * very concise, this package is slightly faster than the built-in sparse - * Cholesky factorization in MATLAB 7.0 (chol), when using the same input - * permutation. - * - * The routines compute the LDL' factorization of a real sparse symmetric - * matrix A (or PAP' if a permutation P is supplied), and solve upper - * and lower triangular systems with the resulting L and D factors. If A is - * positive definite then the factorization will be accurate. A can be - * indefinite (with negative values on the diagonal D), but in this case no - * guarantee of accuracy is provided, since no numeric pivoting is performed. - * - * The n-by-n sparse matrix A is in compressed-column form. The nonzero values - * in column j are stored in Ax [Ap [j] ... Ap [j+1]-1], with corresponding row - * indices in Ai [Ap [j] ... Ap [j+1]-1]. Ap [0] = 0 is required, and thus - * nz = Ap [n] is the number of nonzeros in A. Ap is an int array of size n+1. - * The int array Ai and the double array Ax are of size nz. This data structure - * is identical to the one used by MATLAB, except for the following - * generalizations. The row indices in each column of A need not be in any - * particular order, although they must be in the range 0 to n-1. Duplicate - * entries can be present; any duplicates are summed. That is, if row index i - * appears twice in a column j, then the value of A (i,j) is the sum of the two - * entries. The data structure used here for the input matrix A is more - * flexible than MATLAB's, which requires sorted columns with no duplicate - * entries. - * - * Only the diagonal and upper triangular part of A (or PAP' if a permutation - * P is provided) is accessed. The lower triangular parts of the matrix A or - * PAP' can be present, but they are ignored. - * - * The optional input permutation is provided as an array P of length n. If - * P [k] = j, the row and column j of A is the kth row and column of PAP'. - * If P is present then the factorization is LDL' = PAP' or L*D*L' = A(P,P) in - * 0-based MATLAB notation. If P is not present (a null pointer) then no - * permutation is performed, and the factorization is LDL' = A. - * - * The lower triangular matrix L is stored in the same compressed-column - * form (an int Lp array of size n+1, an int Li array of size Lp [n], and a - * double array Lx of the same size as Li). It has a unit diagonal, which is - * not stored. The row indices in each column of L are always returned in - * ascending order, with no duplicate entries. This format is compatible with - * MATLAB, except that it would be more convenient for MATLAB to include the - * unit diagonal of L. Doing so here would add additional complexity to the - * code, and is thus omitted in the interest of keeping this code short and - * readable. - * - * The elimination tree is held in the Parent [0..n-1] array. It is normally - * not required by the user, but it is required by ldl_numeric. The diagonal - * matrix D is held as an array D [0..n-1] of size n. - * - * -------------------- - * C-callable routines: - * -------------------- - * - * ldl_symbolic: Given the pattern of A, computes the Lp and Parent arrays - * required by ldl_numeric. Takes time proportional to the number of - * nonzeros in L. Computes the inverse Pinv of P if P is provided. - * Also returns Lnz, the count of nonzeros in each column of L below - * the diagonal (this is not required by ldl_numeric). - * ldl_numeric: Given the pattern and numerical values of A, the Lp array, - * the Parent array, and P and Pinv if applicable, computes the - * pattern and numerical values of L and D. - * ldl_lsolve: Solves Lx=b for a dense vector b. - * ldl_dsolve: Solves Dx=b for a dense vector b. - * ldl_ltsolve: Solves L'x=b for a dense vector b. - * ldl_perm: Computes x=Pb for a dense vector b. - * ldl_permt: Computes x=P'b for a dense vector b. - * ldl_valid_perm: checks the validity of a permutation vector - * ldl_valid_matrix: checks the validity of the sparse matrix A - * - * ---------------------------- - * Limitations of this package: - * ---------------------------- - * - * In the interest of keeping this code simple and readable, ldl_symbolic and - * ldl_numeric assume their inputs are valid. You can check your own inputs - * prior to calling these routines with the ldl_valid_perm and ldl_valid_matrix - * routines. Except for the two ldl_valid_* routines, no routine checks to see - * if the array arguments are present (non-NULL). Like all C routines, no - * routine can determine if the arrays are long enough and don't overlap. - * - * The ldl_numeric does check the numerical factorization, however. It returns - * n if the factorization is successful. If D (k,k) is zero, then k is - * returned, and L is only partially computed. - * - * No pivoting to control fill-in is performed, which is often critical for - * obtaining good performance. I recommend that you compute the permutation P - * using AMD or SYMAMD (approximate minimum degree ordering routines), or an - * appropriate graph-partitioning based ordering. See the ldldemo.m routine for - * an example in MATLAB, and the ldlmain.c stand-alone C program for examples of - * how to find P. Routines for manipulating compressed-column matrices are - * available in UMFPACK. AMD, SYMAMD, UMFPACK, and this LDL package are all - * available at http://www.cise.ufl.edu/research/sparse. - * - * ------------------------- - * Possible simplifications: - * ------------------------- - * - * These routines could be made even simpler with a few additional assumptions. - * If no input permutation were performed, the caller would have to permute the - * matrix first, but the computation of Pinv, and the use of P and Pinv could be - * removed. If only the diagonal and upper triangular part of A or PAP' are - * present, then the tests in the "if (i < k)" statement in ldl_symbolic and - * "if (i <= k)" in ldl_numeric, are always true, and could be removed (i can - * equal k in ldl_symbolic, but then the body of the if statement would - * correctly do no work since Flag [k] == k). If we could assume that no - * duplicate entries are present, then the statement Y [i] += Ax [p] could be - * replaced with Y [i] = Ax [p] in ldl_numeric. - * - * -------------------------- - * Description of the method: - * -------------------------- - * - * LDL computes the symbolic factorization by finding the pattern of L one row - * at a time. It does this based on the following theory. Consider a sparse - * system Lx=b, where L, x, and b, are all sparse, and where L comes from a - * Cholesky (or LDL') factorization. The elimination tree (etree) of L is - * defined as follows. The parent of node j is the smallest k > j such that - * L (k,j) is nonzero. Node j has no parent if column j of L is completely zero - * below the diagonal (j is a root of the etree in this case). The nonzero - * pattern of x is the union of the paths from each node i to the root, for - * each nonzero b (i). To compute the numerical solution to Lx=b, we can - * traverse the columns of L corresponding to nonzero values of x. This - * traversal does not need to be done in the order 0 to n-1. It can be done in - * any "topological" order, such that x (i) is computed before x (j) if i is a - * descendant of j in the elimination tree. - * - * The row-form of the LDL' factorization is shown in the MATLAB function - * ldlrow.m in this LDL package. Note that row k of L is found via a sparse - * triangular solve of L (1:k-1, 1:k-1) \ A (1:k-1, k), to use 1-based MATLAB - * notation. Thus, we can start with the nonzero pattern of the kth column of - * A (above the diagonal), follow the paths up to the root of the etree of the - * (k-1)-by-(k-1) leading submatrix of L, and obtain the pattern of the kth row - * of L. Note that we only need the leading (k-1)-by-(k-1) submatrix of L to - * do this. The elimination tree can be constructed as we go. - * - * The symbolic factorization does the same thing, except that it discards the - * pattern of L as it is computed. It simply counts the number of nonzeros in - * each column of L and then constructs the Lp index array when it's done. The - * symbolic factorization does not need to do this in topological order. - * Compare ldl_symbolic with the first part of ldl_numeric, and note that the - * while (len > 0) loop is not present in ldl_symbolic. - * - * LDL Version 1.3, Copyright (c) 2006 by Timothy A Davis, - * University of Florida. All Rights Reserved. Developed while on sabbatical - * at Stanford University and Lawrence Berkeley National Laboratory. Refer to - * the README file for the License. Available at - * http://www.cise.ufl.edu/research/sparse. - */ - -#include "ldl.h" - -/* ========================================================================== */ -/* === ldl_symbolic ========================================================= */ -/* ========================================================================== */ - -/* The input to this routine is a sparse matrix A, stored in column form, and - * an optional permutation P. The output is the elimination tree - * and the number of nonzeros in each column of L. Parent [i] = k if k is the - * parent of i in the tree. The Parent array is required by ldl_numeric. - * Lnz [k] gives the number of nonzeros in the kth column of L, excluding the - * diagonal. - * - * One workspace vector (Flag) of size n is required. - * - * If P is NULL, then it is ignored. The factorization will be LDL' = A. - * Pinv is not computed. In this case, neither P nor Pinv are required by - * ldl_numeric. - * - * If P is not NULL, then it is assumed to be a valid permutation. If - * row and column j of A is the kth pivot, the P [k] = j. The factorization - * will be LDL' = PAP', or A (p,p) in MATLAB notation. The inverse permutation - * Pinv is computed, where Pinv [j] = k if P [k] = j. In this case, both P - * and Pinv are required as inputs to ldl_numeric. - * - * The floating-point operation count of the subsequent call to ldl_numeric - * is not returned, but could be computed after ldl_symbolic is done. It is - * the sum of (Lnz [k]) * (Lnz [k] + 2) for k = 0 to n-1. - */ - -void LDL_symbolic -( - LDL_int n, /* A and L are n-by-n, where n >= 0 */ - LDL_int Ap [ ], /* input of size n+1, not modified */ - LDL_int Ai [ ], /* input of size nz=Ap[n], not modified */ - LDL_int Lp [ ], /* output of size n+1, not defined on input */ - LDL_int Parent [ ], /* output of size n, not defined on input */ - LDL_int Lnz [ ], /* output of size n, not defined on input */ - LDL_int Flag [ ], /* workspace of size n, not defn. on input or output */ - LDL_int P [ ], /* optional input of size n */ - LDL_int Pinv [ ] /* optional output of size n (used if P is not NULL) */ -) -{ - LDL_int i, k, p, kk, p2 ; - if (P) - { - /* If P is present then compute Pinv, the inverse of P */ - for (k = 0 ; k < n ; k++) - { - Pinv [P [k]] = k ; - } - } - for (k = 0 ; k < n ; k++) - { - /* L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k) */ - Parent [k] = -1 ; /* parent of k is not yet known */ - Flag [k] = k ; /* mark node k as visited */ - Lnz [k] = 0 ; /* count of nonzeros in column k of L */ - kk = (P) ? (P [k]) : (k) ; /* kth original, or permuted, column */ - p2 = Ap [kk+1] ; - for (p = Ap [kk] ; p < p2 ; p++) - { - /* A (i,k) is nonzero (original or permuted A) */ - i = (Pinv) ? (Pinv [Ai [p]]) : (Ai [p]) ; - if (i < k) - { - /* follow path from i to root of etree, stop at flagged node */ - for ( ; Flag [i] != k ; i = Parent [i]) - { - /* find parent of i if not yet determined */ - if (Parent [i] == -1) Parent [i] = k ; - Lnz [i]++ ; /* L (k,i) is nonzero */ - Flag [i] = k ; /* mark i as visited */ - } - } - } - } - /* construct Lp index array from Lnz column counts */ - Lp [0] = 0 ; - for (k = 0 ; k < n ; k++) - { - Lp [k+1] = Lp [k] + Lnz [k] ; - } -} - - -/* ========================================================================== */ -/* === ldl_numeric ========================================================== */ -/* ========================================================================== */ - -/* Given a sparse matrix A (the arguments n, Ap, Ai, and Ax) and its symbolic - * analysis (Lp and Parent, and optionally P and Pinv), compute the numeric LDL' - * factorization of A or PAP'. The outputs of this routine are arguments Li, - * Lx, and D. It also requires three size-n workspaces (Y, Pattern, and Flag). - */ - -LDL_int LDL_numeric /* returns n if successful, k if D (k,k) is zero */ -( - LDL_int n, /* A and L are n-by-n, where n >= 0 */ - LDL_int Ap [ ], /* input of size n+1, not modified */ - LDL_int Ai [ ], /* input of size nz=Ap[n], not modified */ - double Ax [ ], /* input of size nz=Ap[n], not modified */ - LDL_int Lp [ ], /* input of size n+1, not modified */ - LDL_int Parent [ ], /* input of size n, not modified */ - LDL_int Lnz [ ], /* output of size n, not defn. on input */ - LDL_int Li [ ], /* output of size lnz=Lp[n], not defined on input */ - double Lx [ ], /* output of size lnz=Lp[n], not defined on input */ - double D [ ], /* output of size n, not defined on input */ - double Y [ ], /* workspace of size n, not defn. on input or output */ - LDL_int Pattern [ ],/* workspace of size n, not defn. on input or output */ - LDL_int Flag [ ], /* workspace of size n, not defn. on input or output */ - LDL_int P [ ], /* optional input of size n */ - LDL_int Pinv [ ] /* optional input of size n */ -) -{ - double yi, l_ki ; - LDL_int i, k, p, kk, p2, len, top ; - for (k = 0 ; k < n ; k++) - { - /* compute nonzero Pattern of kth row of L, in topological order */ - Y [k] = 0.0 ; /* Y(0:k) is now all zero */ - top = n ; /* stack for pattern is empty */ - Flag [k] = k ; /* mark node k as visited */ - Lnz [k] = 0 ; /* count of nonzeros in column k of L */ - kk = (P) ? (P [k]) : (k) ; /* kth original, or permuted, column */ - p2 = Ap [kk+1] ; - for (p = Ap [kk] ; p < p2 ; p++) - { - i = (Pinv) ? (Pinv [Ai [p]]) : (Ai [p]) ; /* get A(i,k) */ - if (i <= k) - { - Y [i] += Ax [p] ; /* scatter A(i,k) into Y (sum duplicates) */ - for (len = 0 ; Flag [i] != k ; i = Parent [i]) - { - Pattern [len++] = i ; /* L(k,i) is nonzero */ - Flag [i] = k ; /* mark i as visited */ - } - while (len > 0) Pattern [--top] = Pattern [--len] ; - } - } - /* compute numerical values kth row of L (a sparse triangular solve) */ - D [k] = Y [k] ; /* get D(k,k) and clear Y(k) */ - Y [k] = 0.0 ; - for ( ; top < n ; top++) - { - i = Pattern [top] ; /* Pattern [top:n-1] is pattern of L(:,k) */ - yi = Y [i] ; /* get and clear Y(i) */ - Y [i] = 0.0 ; - p2 = Lp [i] + Lnz [i] ; - for (p = Lp [i] ; p < p2 ; p++) - { - Y [Li [p]] -= Lx [p] * yi ; - } - l_ki = yi / D [i] ; /* the nonzero entry L(k,i) */ - D [k] -= l_ki * yi ; - Li [p] = k ; /* store L(k,i) in column form of L */ - Lx [p] = l_ki ; - Lnz [i]++ ; /* increment count of nonzeros in col i */ - } - if (D [k] == 0.0) return (k) ; /* failure, D(k,k) is zero */ - } - return (n) ; /* success, diagonal of D is all nonzero */ -} - - -/* ========================================================================== */ -/* === ldl_lsolve: solve Lx=b ============================================== */ -/* ========================================================================== */ - -void LDL_lsolve -( - LDL_int n, /* L is n-by-n, where n >= 0 */ - double X [ ], /* size n. right-hand-side on input, soln. on output */ - LDL_int Lp [ ], /* input of size n+1, not modified */ - LDL_int Li [ ], /* input of size lnz=Lp[n], not modified */ - double Lx [ ] /* input of size lnz=Lp[n], not modified */ -) -{ - LDL_int j, p, p2 ; - for (j = 0 ; j < n ; j++) - { - p2 = Lp [j+1] ; - for (p = Lp [j] ; p < p2 ; p++) - { - X [Li [p]] -= Lx [p] * X [j] ; - } - } -} - - -/* ========================================================================== */ -/* === ldl_dsolve: solve Dx=b ============================================== */ -/* ========================================================================== */ - -void LDL_dsolve -( - LDL_int n, /* D is n-by-n, where n >= 0 */ - double X [ ], /* size n. right-hand-side on input, soln. on output */ - double D [ ] /* input of size n, not modified */ -) -{ - LDL_int j ; - for (j = 0 ; j < n ; j++) - { - X [j] /= D [j] ; - } -} - - -/* ========================================================================== */ -/* === ldl_ltsolve: solve L'x=b ============================================ */ -/* ========================================================================== */ - -void LDL_ltsolve -( - LDL_int n, /* L is n-by-n, where n >= 0 */ - double X [ ], /* size n. right-hand-side on input, soln. on output */ - LDL_int Lp [ ], /* input of size n+1, not modified */ - LDL_int Li [ ], /* input of size lnz=Lp[n], not modified */ - double Lx [ ] /* input of size lnz=Lp[n], not modified */ -) -{ - int j, p, p2 ; - for (j = n-1 ; j >= 0 ; j--) - { - p2 = Lp [j+1] ; - for (p = Lp [j] ; p < p2 ; p++) - { - X [j] -= Lx [p] * X [Li [p]] ; - } - } -} - - -/* ========================================================================== */ -/* === ldl_perm: permute a vector, x=Pb ===================================== */ -/* ========================================================================== */ - -void LDL_perm -( - LDL_int n, /* size of X, B, and P */ - double X [ ], /* output of size n. */ - double B [ ], /* input of size n. */ - LDL_int P [ ] /* input permutation array of size n. */ -) -{ - LDL_int j ; - for (j = 0 ; j < n ; j++) - { - X [j] = B [P [j]] ; - } -} - - -/* ========================================================================== */ -/* === ldl_permt: permute a vector, x=P'b =================================== */ -/* ========================================================================== */ - -void LDL_permt -( - LDL_int n, /* size of X, B, and P */ - double X [ ], /* output of size n. */ - double B [ ], /* input of size n. */ - LDL_int P [ ] /* input permutation array of size n. */ -) -{ - LDL_int j ; - for (j = 0 ; j < n ; j++) - { - X [P [j]] = B [j] ; - } -} - - -/* ========================================================================== */ -/* === ldl_valid_perm: check if a permutation vector is valid =============== */ -/* ========================================================================== */ - -LDL_int LDL_valid_perm /* returns 1 if valid, 0 otherwise */ -( - LDL_int n, - LDL_int P [ ], /* input of size n, a permutation of 0:n-1 */ - LDL_int Flag [ ] /* workspace of size n */ -) -{ - LDL_int j, k ; - if (n < 0 || !Flag) - { - return (0) ; /* n must be >= 0, and Flag must be present */ - } - if (!P) - { - return (1) ; /* If NULL, P is assumed to be the identity perm. */ - } - for (j = 0 ; j < n ; j++) - { - Flag [j] = 0 ; /* clear the Flag array */ - } - for (k = 0 ; k < n ; k++) - { - j = P [k] ; - if (j < 0 || j >= n || Flag [j] != 0) - { - return (0) ; /* P is not valid */ - } - Flag [j] = 1 ; - } - return (1) ; /* P is valid */ -} - - -/* ========================================================================== */ -/* === ldl_valid_matrix: check if a sparse matrix is valid ================== */ -/* ========================================================================== */ - -/* This routine checks to see if a sparse matrix A is valid for input to - * ldl_symbolic and ldl_numeric. It returns 1 if the matrix is valid, 0 - * otherwise. A is in sparse column form. The numerical values in column j - * are stored in Ax [Ap [j] ... Ap [j+1]-1], with row indices in - * Ai [Ap [j] ... Ap [j+1]-1]. The Ax array is not checked. - */ - -LDL_int LDL_valid_matrix -( - LDL_int n, - LDL_int Ap [ ], - LDL_int Ai [ ] -) -{ - LDL_int j, p ; - if (n < 0 || !Ap || !Ai || Ap [0] != 0) - { - return (0) ; /* n must be >= 0, and Ap and Ai must be present */ - } - for (j = 0 ; j < n ; j++) - { - if (Ap [j] > Ap [j+1]) - { - return (0) ; /* Ap must be monotonically nondecreasing */ - } - } - for (p = 0 ; p < Ap [n] ; p++) - { - if (Ai [p] < 0 || Ai [p] >= n) - { - return (0) ; /* row indices must be in the range 0 to n-1 */ - } - } - return (1) ; /* matrix is valid */ -} diff --git a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/ldl.h b/Sofa/Component/LinearSolver/Direct/extlibs/csparse/ldl.h deleted file mode 100644 index 64d3dbb2d2e2..000000000000 --- a/Sofa/Component/LinearSolver/Direct/extlibs/csparse/ldl.h +++ /dev/null @@ -1,111 +0,0 @@ -/* ========================================================================== */ -/* === ldl.h: include file for the LDL package ============================= */ -/* ========================================================================== */ - -/* LDL Copyright (c) Timothy A Davis, - * University of Florida. All Rights Reserved. See README for the License. - */ - -#include "UFconfig.h" - -#ifdef LDL_LONG -#define LDL_int UF_long -#define LDL_ID UF_long_id - -#define LDL_symbolic ldl_l_symbolic -#define LDL_numeric ldl_l_numeric -#define LDL_lsolve ldl_l_lsolve -#define LDL_dsolve ldl_l_dsolve -#define LDL_ltsolve ldl_l_ltsolve -#define LDL_perm ldl_l_perm -#define LDL_permt ldl_l_permt -#define LDL_valid_perm ldl_l_valid_perm -#define LDL_valid_matrix ldl_l_valid_matrix - -#else -#define LDL_int int -#define LDL_ID "%d" - -#define LDL_symbolic ldl_symbolic -#define LDL_numeric ldl_numeric -#define LDL_lsolve ldl_lsolve -#define LDL_dsolve ldl_dsolve -#define LDL_ltsolve ldl_ltsolve -#define LDL_perm ldl_perm -#define LDL_permt ldl_permt -#define LDL_valid_perm ldl_valid_perm -#define LDL_valid_matrix ldl_valid_matrix - -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -/* ========================================================================== */ -/* === int version ========================================================== */ -/* ========================================================================== */ - -void ldl_symbolic (int n, int Ap [ ], int Ai [ ], int Lp [ ], - int Parent [ ], int Lnz [ ], int Flag [ ], int P [ ], int Pinv [ ]) ; - -int ldl_numeric (int n, int Ap [ ], int Ai [ ], double Ax [ ], - int Lp [ ], int Parent [ ], int Lnz [ ], int Li [ ], double Lx [ ], - double D [ ], double Y [ ], int Pattern [ ], int Flag [ ], - int P [ ], int Pinv [ ]) ; - -void ldl_lsolve (int n, double X [ ], int Lp [ ], int Li [ ], - double Lx [ ]) ; - -void ldl_dsolve (int n, double X [ ], double D [ ]) ; - -void ldl_ltsolve (int n, double X [ ], int Lp [ ], int Li [ ], - double Lx [ ]) ; - -void ldl_perm (int n, double X [ ], double B [ ], int P [ ]) ; -void ldl_permt (int n, double X [ ], double B [ ], int P [ ]) ; - -int ldl_valid_perm (int n, int P [ ], int Flag [ ]) ; -int ldl_valid_matrix ( int n, int Ap [ ], int Ai [ ]) ; - -/* ========================================================================== */ -/* === long version ========================================================= */ -/* ========================================================================== */ - -void ldl_l_symbolic (UF_long n, UF_long Ap [ ], UF_long Ai [ ], UF_long Lp [ ], - UF_long Parent [ ], UF_long Lnz [ ], UF_long Flag [ ], UF_long P [ ], - UF_long Pinv [ ]) ; - -UF_long ldl_l_numeric (UF_long n, UF_long Ap [ ], UF_long Ai [ ], double Ax [ ], - UF_long Lp [ ], UF_long Parent [ ], UF_long Lnz [ ], UF_long Li [ ], - double Lx [ ], double D [ ], double Y [ ], UF_long Pattern [ ], - UF_long Flag [ ], UF_long P [ ], UF_long Pinv [ ]) ; - -void ldl_l_lsolve (UF_long n, double X [ ], UF_long Lp [ ], UF_long Li [ ], - double Lx [ ]) ; - -void ldl_l_dsolve (UF_long n, double X [ ], double D [ ]) ; - -void ldl_l_ltsolve (UF_long n, double X [ ], UF_long Lp [ ], UF_long Li [ ], - double Lx [ ]) ; - -void ldl_l_perm (UF_long n, double X [ ], double B [ ], UF_long P [ ]) ; -void ldl_l_permt (UF_long n, double X [ ], double B [ ], UF_long P [ ]) ; - -UF_long ldl_l_valid_perm (UF_long n, UF_long P [ ], UF_long Flag [ ]) ; -UF_long ldl_l_valid_matrix ( UF_long n, UF_long Ap [ ], UF_long Ai [ ]) ; - -/* ========================================================================== */ -/* === LDL version ========================================================== */ -/* ========================================================================== */ - -#define LDL_DATE "Nov 1, 2007" -#define LDL_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) -#define LDL_MAIN_VERSION 2 -#define LDL_SUB_VERSION 0 -#define LDL_SUBSUB_VERSION 1 -#define LDL_VERSION LDL_VERSION_CODE(LDL_MAIN_VERSION,LDL_SUB_VERSION) - -#if defined(__cplusplus) -} //extern "C" -#endif diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/EigenDirectSparseSolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/EigenDirectSparseSolver.inl index 6795096feaf6..8416631c581f 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/EigenDirectSparseSolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/EigenDirectSparseSolver.inl @@ -66,11 +66,10 @@ void EigenDirectSparseSolver Mfiltered.compress(); } - if (!m_map) - { - m_map = std::make_unique(Mfiltered.rows(), Mfiltered.cols(), Mfiltered.getColsValue().size(), - (typename EigenSparseMatrixMap::StorageIndex*)Mfiltered.rowBegin.data(), (typename EigenSparseMatrixMap::StorageIndex*)Mfiltered.colsIndex.data(), Mfiltered.colsValue.data()); - } + m_map = std::make_unique(Mfiltered.rows(), Mfiltered.cols(), Mfiltered.getColsValue().size(), + (typename EigenSparseMatrixMap::StorageIndex*)Mfiltered.rowBegin.data(), + (typename EigenSparseMatrixMap::StorageIndex*)Mfiltered.colsIndex.data(), + Mfiltered.colsValue.data()); const bool analyzePattern = (MfilteredrowBegin != Mfiltered.rowBegin) || (MfilteredcolsIndex != Mfiltered.colsIndex); diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/PrecomputedLinearSolver.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/PrecomputedLinearSolver.h index 1b5f0363237c..c813cee4291d 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/PrecomputedLinearSolver.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/PrecomputedLinearSolver.h @@ -92,9 +92,7 @@ class PrecomputedLinearSolver : public sofa::component::linearsolver::MatrixLine void invert(TMatrix& M) override; void setSystemMBKMatrix(const core::MechanicalParams* mparams) override; void loadMatrix(TMatrix& M); -#if SOFASPARSESOLVER_HAVE_CSPARSE - void loadMatrixWithCSparse(TMatrix& M); -#endif + void loadMatrixWithCholeskyDecomposition(TMatrix& M); bool addJMInvJt(linearalgebra::BaseMatrix* result, linearalgebra::BaseMatrix* J, SReal fact) override; /// Returns the sofa template name. By default the name of the c++ class signature is exposed... diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/PrecomputedLinearSolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/PrecomputedLinearSolver.inl index 0eb64a99dfb0..03b9d5538b69 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/PrecomputedLinearSolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/PrecomputedLinearSolver.inl @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include #include @@ -37,10 +39,6 @@ #include -#if SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE && !defined(SOFA_FLOAT) -#include -#endif - #include namespace sofa::component::linearsolver::direct @@ -89,13 +87,8 @@ void PrecomputedLinearSolver::loadMatrix(TMatrix& M) ss << this->getContext()->getName() << "-" << systemSize << "-" << dt << ".comp"; if(! use_file.getValue() || ! internalData.readFile(ss.str().c_str(),systemSize) ) { -#if SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE && !defined(SOFA_FLOAT) - loadMatrixWithCSparse(M); + loadMatrixWithCholeskyDecomposition(M); if (use_file.getValue()) internalData.writeFile(ss.str().c_str(),systemSize); -#else - SOFA_UNUSED(M); - msg_error()<< "CSPARSE support is required to invert the matrix"; -#endif } for (unsigned int j=0; j::loadMatrix(TMatrix& M) } } -#if SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE && !defined(SOFA_FLOAT) template -void PrecomputedLinearSolver::loadMatrixWithCSparse(TMatrix& M) +void PrecomputedLinearSolver::loadMatrixWithCholeskyDecomposition(TMatrix& M) { using namespace sofa::linearalgebra; msg_info() << "Compute the initial invert matrix with CS_PARSE" ; @@ -123,7 +115,7 @@ void PrecomputedLinearSolver::loadMatrixWithCSparse(TMatrix& M) matSolv.resize(systemSize,systemSize); r.resize(systemSize); b.resize(systemSize); - SparseCholeskySolver, FullVector > solver; + EigenSimplicialLLT solver; for (unsigned int j=0; j::loadMatrixWithCSparse(TMatrix& M) msg_info() << "Precomputing constraint correction : " << std::fixed << 100.0f << " % " << '\xd'; } -#endif // SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE && !defined(SOFA_FLOAT) template void PrecomputedLinearSolver::invert(TMatrix& /*M*/) {} diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.cpp b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.cpp deleted file mode 100644 index d283bea94ffe..000000000000 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************** -* SOFA, Simulation Open-Framework Architecture * -* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU Lesser General Public License as published by * -* the Free Software Foundation; either version 2.1 of the License, or (at * -* your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but WITHOUT * -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * -* for more details. * -* * -* You should have received a copy of the GNU Lesser General Public License * -* along with this program. If not, see . * -******************************************************************************* -* Authors: The SOFA Team and external contributors (see Authors.txt) * -* * -* Contact information: contact@sofa-framework.org * -******************************************************************************/ -#define SOFA_COMPONENT_LINEARSOLVER_SPARSECHOLESKYSOLVER_CPP -#include -#include - -namespace sofa::component::linearsolver::direct -{ - -using namespace sofa::linearalgebra; - -#ifdef SOFA_FLOAT -SOFA_PRAGMA_WARNING("SparseCholeskySolver does not support float as scalar.") -#else // SOFA_DOUBLE -int SparseCholeskySolverClass = - core::RegisterObject( - "Direct linear solver based on Sparse Cholesky factorization, implemented with the " - "CSPARSE library") - .add, FullVector > >(); - -template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API - SparseCholeskySolver, FullVector >; -#endif // SOFA_FLOAT - -} // namespace sofa::component::linearsolver::direct diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.h index 9fd72c37db46..e4bf3e0b8cf1 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.h @@ -20,61 +20,8 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once +#include -#include - -#include -#include -#include -#include -#include - -namespace sofa::component::linearsolver::direct -{ - -// Direct linear solver based on Sparse Cholesky factorization, implemented with the CSPARSE library -template -class SparseCholeskySolver : public sofa::component::linearsolver::MatrixLinearSolver -{ -public: - SOFA_CLASS(SOFA_TEMPLATE2(SparseCholeskySolver,TMatrix,TVector),SOFA_TEMPLATE2(sofa::component::linearsolver::MatrixLinearSolver,TMatrix,TVector)); - - typedef TMatrix Matrix; - typedef TVector Vector; - - SparseCholeskySolver(); - ~SparseCholeskySolver() override; - - void solve (Matrix& M, Vector& x, Vector& b) override; - void invert(Matrix& M) override; - - void parse(core::objectmodel::BaseObjectDescription *arg) override; - -protected: - - SOFA_ATTRIBUTE_DEPRECATED__SOLVER_DIRECT_VERBOSEDATA() - Data f_verbose; ///< Dump system state at each iteration - - cs A; - cs* permuted_A; - css *S; - csn *N; - int * A_i; ///< row indices, size nzmax - int * A_p; ///< column pointers (size n+1) or col indices (size nzmax) - type::vector Previous_colptr,Previous_rowind; ///< shape of the matrix at the previous step - type::vector perm,iperm; ///< fill reducing permutation - type::vector A_x,z_tmp,r_tmp,tmp; - bool notSameShape; - - Data d_typePermutation; - - void suiteSparseFactorization(bool applyPermutation); - - css* symbolic_Chol(cs *A); -}; - -#if !defined(SOFA_COMPONENT_LINEARSOLVER_SPARSECHOLESKYSOLVER_CPP) -extern template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API SparseCholeskySolver< sofa::linearalgebra::CompressedRowSparseMatrix, sofa::linearalgebra::FullVector >; -#endif - -} // namespace sofa::component::linearsolver::direct +SOFA_PRAGMA_ERROR( \ + "This header has been DISABLED since v23.12. " \ + "To fix this error you must use the CSparseSolvers plugins. " ) diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.inl index 70190cd92c58..e4bf3e0b8cf1 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCholeskySolver.inl @@ -20,206 +20,8 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once +#include -#include -#include - -namespace sofa::component::linearsolver::direct -{ - -template -SparseCholeskySolver::SparseCholeskySolver() - : S(nullptr), N(nullptr) - , d_typePermutation(initData(&d_typePermutation, {"None", "SuiteSparse", "METIS"}, - "permutation", "Type of fill reducing permutation")) -{} - -template -SparseCholeskySolver::~SparseCholeskySolver() -{ - if (S) cs_sfree (S); - if (N) cs_nfree (N); -} - -template -void SparseCholeskySolver::solve (Matrix& /*M*/, Vector& x, Vector& b) -{ - const int n = A.n; - - SCOPED_TIMER_VARNAME(solveTimer, "solve"); - - switch( d_typePermutation.getValue().getSelectedId() ) - { - case 0://None->identity - case 1://SuiteSparse - if(N) - { - cs_ipvec (n, S->Pinv, (double*)b.ptr() , tmp.data() ); //x = P*b , permutation on rows - cs_lsolve (N->L, tmp.data() ); //x = L\x - cs_ltsolve (N->L, tmp.data() ); //x = L'\x/ - cs_pvec (n, S->Pinv, tmp.data() , (double*)x.ptr() ); //x = P'*x , permutation on columns - } - else - { - msg_error() << "Cannot solve system due to invalid factorization"; - } - break; - - case 2://METIS - if(N) - { - cs_ipvec (n, perm.data(), (double*)b.ptr() , tmp.data() ); //x = P*b , permutation on rows - cs_lsolve (N->L, tmp.data() ); //x = L\x - cs_ltsolve (N->L, tmp.data() ); //x = L'\x/ - cs_pvec (n, perm.data() , tmp.data() , (double*)x.ptr() ); //x = P'*x , permutation on columns - } - else - { - msg_error() << "Cannot solve system due to invalid factorization"; - } - break; - - default: - break; - - } - -} - -template -void SparseCholeskySolver::invert(Matrix& M) -{ - if (N) cs_nfree(N); - M.compress(); - - A.nzmax = M.getColsValue().size(); // maximum number of entries - A_p = (int *) &(M.getRowBegin()[0]); - A_i = (int *) &(M.getColsIndex()[0]); - A_x.resize(A.nzmax); - for (int i=0; iidentity - suiteSparseFactorization(false); - break; - - case 1:// SuiteSparse - suiteSparseFactorization(true); - break; - - case 2:// METIS - if( notSameShape ) - { - perm.resize(A.n); - iperm.resize(A.n); - - fillReducingPermutation( A , iperm.data(), perm.data() ); // compute the fill reducing permutation - } - - permuted_A = cs_permute( &A , perm.data() , iperm.data() , 1); - - if ( notSameShape ) - { - if (S) cs_sfree(S); - S = symbolic_Chol( permuted_A ); - } // symbolic analysis - - N = cs_chol (permuted_A, S) ; // numeric Cholesky factorization - assert(N); - - cs_free(permuted_A); - break; - } - } - - // store the shape of the matrix - if ( notSameShape ) - { - Previous_rowind.clear(); - Previous_colptr.resize(A.n +1); - for(int i=0 ; i -void SparseCholeskySolver::parse(core::objectmodel::BaseObjectDescription* arg) -{ - if (arg->getAttribute("verbose")) - { - msg_warning() << "Attribute 'verbose' has no use in this component. " - "To disable this warning, remove the attribute from the scene."; - } - - Inherit1::parse(arg); -} - -template -void SparseCholeskySolver::suiteSparseFactorization(bool applyPermutation) -{ - if( notSameShape ) - { - if (S) - { - cs_sfree(S); - } - const auto order = applyPermutation ? 0 : -1; - S = cs_schol (&A, order); - } - assert(S); - assert(S->cp); - assert(S->parent); - N = cs_chol (&A, S) ; // numeric Cholesky factorization - msg_error_when(!N) << "Matrix could not be factorized: possibly not positive-definite"; -} - -template -css* SparseCholeskySolver::symbolic_Chol(cs *A) -{ //based on cs_schol - int n, *c, *post; - cs *C ; - css *S ; - if (!A) return (NULL) ; // check inputs - n = A->n ; - S = (css*)cs_calloc (1, sizeof (css)) ; // allocate symbolic analysis - if (!S) return (NULL) ; // out of memory - C = cs_symperm (A, S->Pinv, 0) ; // C = spones(triu(A(P,P))) - S->parent = cs_etree (C, 0) ; // find etree of C - post = cs_post (n, S->parent) ; // postorder the etree - c = cs_counts (C, S->parent, post, 0) ; // find column counts of chol(C) - cs_free (post) ; - cs_spfree (C) ; - S->cp = (int*)cs_malloc (n+1, sizeof (int)) ; // find column pointers for L - S->unz = S->lnz = cs_cumsum (S->cp, c, n) ; - // we do not use the permutation of SuiteSparse - S->Q = nullptr ; // permutation on columns set to identity - S->Pinv = nullptr; // permutation on rows set to identity - cs_free (c) ; - return ((S->lnz >= 0) ? S : cs_sfree (S)) ; -} - -} // namespace sofa::component::linearsolver::direct +SOFA_PRAGMA_ERROR( \ + "This header has been DISABLED since v23.12. " \ + "To fix this error you must use the CSparseSolvers plugins. " ) diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCommon.cpp b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCommon.cpp index 91439016f579..af4764e0ac36 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCommon.cpp +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCommon.cpp @@ -19,10 +19,12 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ - - #include +extern "C" { +#include +} + namespace sofa::component::linearsolver::direct { void csrToAdj(int n, int * M_colptr, int * M_rowind, type::vector& adj, type::vector& xadj , type::vector& t_adj , type::vector& t_xadj, type::vector& tran_countvec) @@ -86,14 +88,13 @@ void csrToAdj(int n, int * M_colptr, int * M_rowind, type::vector& adj, typ } } - -void fillReducingPermutation(const cs &A,int * perm,int * invperm) +void fillReducingPermutation(int nbColumns, int *columns, int* rowIndices, + int * perm,int * invperm) { - int n = A.n; sofa::type::vector adj, xadj, t_adj, t_xadj, tran_countvec; - csrToAdj( A.n, A.p , A.i , adj, xadj, t_adj, t_xadj, tran_countvec ); - METIS_NodeND(&n, xadj.data(), adj.data(), nullptr, nullptr, perm, invperm); - + csrToAdj( nbColumns, columns , rowIndices , adj, xadj, t_adj, t_xadj, tran_countvec ); + METIS_NodeND(&nbColumns, xadj.data(), adj.data(), nullptr, nullptr, perm, invperm); } + } diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCommon.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCommon.h index a2334a40010f..37cf3400d528 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCommon.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseCommon.h @@ -24,11 +24,6 @@ #include #include -#include - -extern "C" { -#include -} namespace sofa::component::linearsolver::direct { @@ -46,7 +41,9 @@ SOFA_COMPONENT_LINEARSOLVER_DIRECT_API void csrToAdj(int n, int * M_colptr, int * M_rowind, type::vector& adj, type::vector& xadj, type::vector& t_adj, type::vector& t_xadj, type::vector& tran_countvec ); // compute the fill reducing permutation via METIS -void fillReducingPermutation(const cs &A,int * perm,int * invperm); +SOFA_COMPONENT_LINEARSOLVER_DIRECT_API +void fillReducingPermutation(int nbColumns, int *columns, int* rowIndices, + int * perm,int * invperm); // compare the shape of two matrix given in CSR format, return false if the matrices have the same shape and return true if their shapes are different inline bool compareMatrixShape(int s_M, int * M_colptr,int * M_rowind, int s_P, int * P_colptr,int * P_rowind) { diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolverImpl.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolverImpl.h index cf1d51c1f4aa..2baf93b64ee0 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolverImpl.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLDLSolverImpl.h @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.cpp b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.cpp deleted file mode 100644 index dd4faff9814e..000000000000 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** -* SOFA, Simulation Open-Framework Architecture * -* (c) 2006 INRIA, USTL, UJF, CNRS, MGH * -* * -* This program is free software; you can redistribute it and/or modify it * -* under the terms of the GNU Lesser General Public License as published by * -* the Free Software Foundation; either version 2.1 of the License, or (at * -* your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, but WITHOUT * -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * -* for more details. * -* * -* You should have received a copy of the GNU Lesser General Public License * -* along with this program. If not, see . * -******************************************************************************* -* Authors: The SOFA Team and external contributors (see Authors.txt) * -* * -* Contact information: contact@sofa-framework.org * -******************************************************************************/ -#define SOFA_COMPONENT_LINEARSOLVER_SPARSELUSOLVER_CPP -#include -#include -#include - -namespace sofa::component::linearsolver::direct -{ - -using namespace sofa::linearalgebra; - -// dont try to compile if floating point is float -#ifdef SOFA_FLOAT -SOFA_PRAGMA_WARNING("SparseLUSolver does not support float as scalar.") -#else // SOFA_DOUBLE -int SparseLUSolverClass = core::RegisterObject("Direct linear solver based on Sparse LU factorization, implemented with the CSPARSE library") - .add< SparseLUSolver< CompressedRowSparseMatrix, FullVector > >() - .add< SparseLUSolver< CompressedRowSparseMatrix >,FullVector > >() - ; - -template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API SparseLUSolver< CompressedRowSparseMatrix, FullVector >; -template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API SparseLUSolver< CompressedRowSparseMatrix >, FullVector >; -#endif // SOFA_FLOAT - -} // namespace sofa::component::linearsolver::direct - diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.h b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.h index b6ebba1a2adc..e4bf3e0b8cf1 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.h +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.h @@ -20,89 +20,8 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once -#include +#include -#include -#include -#include -#include - -namespace sofa::component::linearsolver::direct -{ - -//defaut structure for a LU factorization -template -class SparseLUInvertData : public MatrixInvertData { -public : - - css *S; ///< store the permutations and the number of non null values by rows and by lines of the LU factorization - csn *N; ///< store the partial pivot and the LU factorization - cs A; - cs* permuted_A; - type::vector perm,iperm; ///< fill reducing permutation - type::vector Previous_colptr,Previous_rowind; ///< shape of the matrix at the previous step - type::vector A_i, A_p; - type::vector A_x; - Real * tmp; - bool notSameShape; - SparseLUInvertData() - { - S=nullptr; N=nullptr; tmp=nullptr; - } - - ~SparseLUInvertData() - { - if (S) cs_sfree (S); - if (N) cs_nfree (N); - if (tmp) cs_free (tmp); - } -}; - -// Direct linear solver based on Sparse LU factorization, implemented with the CSPARSE library -template -class SparseLUSolver : public sofa::component::linearsolver::MatrixLinearSolver -{ -public: - SOFA_CLASS(SOFA_TEMPLATE3(SparseLUSolver,TMatrix,TVector,TThreadManager),SOFA_TEMPLATE3(sofa::component::linearsolver::MatrixLinearSolver,TMatrix,TVector,TThreadManager)); - - typedef TMatrix Matrix; - typedef TVector Vector; - typedef typename Matrix::Real Real; - - typedef sofa::component::linearsolver::MatrixLinearSolver Inherit; - - SOFA_ATTRIBUTE_DEPRECATED__SOLVER_DIRECT_VERBOSEDATA() - Data f_verbose; ///< Dump system state at each iteration - - Data f_tol; ///< tolerance of factorization - - void solve (Matrix& M, Vector& x, Vector& b) override; - void invert(Matrix& M) override; - - SparseLUSolver(); - - bool supportNonSymmetricSystem() const override { return true; } - - void parse(core::objectmodel::BaseObjectDescription *arg) override; - -protected : - - Data d_typePermutation; - Data d_L_nnz; ///< Number of non-zero values in the lower triangular matrix of the factorization. The lower, the faster the system is solved. - - css* symbolic_LU(cs *A); - - MatrixInvertData * createInvertData() override { - return new SparseLUInvertData(); - } - - std::unique_ptr > Mfiltered; - -}; - - -#if !defined(SOFA_COMPONENT_LINEARSOLVER_SPARSELUSOLVER_CPP) -extern template class SOFA_COMPONENT_LINEARSOLVER_DIRECT_API SparseLUSolver< sofa::linearalgebra::CompressedRowSparseMatrix< SReal>, sofa::linearalgebra::FullVector >; -#endif - -} // namespace sofa::component::linearsolver::direct +SOFA_PRAGMA_ERROR( \ + "This header has been DISABLED since v23.12. " \ + "To fix this error you must use the CSparseSolvers plugins. " ) diff --git a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.inl b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.inl index 7c0339024f26..e4bf3e0b8cf1 100644 --- a/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.inl +++ b/Sofa/Component/LinearSolver/Direct/src/sofa/component/linearsolver/direct/SparseLUSolver.inl @@ -20,234 +20,8 @@ * Contact information: contact@sofa-framework.org * ******************************************************************************/ #pragma once +#include -#include -#include - -namespace sofa::component::linearsolver::direct -{ - -using namespace sofa::defaulttype; -using namespace sofa::core::behavior; -using namespace sofa::simulation; -using namespace sofa::core::objectmodel; -using sofa::helper::system::thread::CTime; -using sofa::helper::system::thread::ctime_t; -using std::cerr; -using std::endl; - -template -SparseLUSolver::SparseLUSolver() - : f_tol( initData(&f_tol,0.001,"tolerance","tolerance of factorization") ) - , d_typePermutation(initData(&d_typePermutation , "permutation", "Type of fill reducing permutation")) - , d_L_nnz(initData(&d_L_nnz, 0, "L_nnz", "Number of non-zero values in the lower triangular matrix of the factorization. The lower, the faster the system is solved.", true, true)) -{ - sofa::helper::OptionsGroup d_typePermutationOptions{"None", "SuiteSparse", "METIS"}; - d_typePermutationOptions.setSelectedItem(0); // default None - d_typePermutation.setValue(d_typePermutationOptions); -} - -template -void SparseLUSolver::parse( - core::objectmodel::BaseObjectDescription* arg) -{ - if (arg->getAttribute("verbose")) - { - msg_warning() << "Attribute 'verbose' has no use in this component. " - "To disable this warning, remove the attribute from the scene."; - } - - Inherit::parse(arg); -} - - -template -void SparseLUSolver::solve (Matrix& M, Vector& x, Vector& b) -{ - SparseLUInvertData * invertData = (SparseLUInvertData*) this->getMatrixInvertData(&M); - const int n = invertData->A.n; - - { - SCOPED_TIMER_VARNAME(solveTimer, "solve"); - switch( d_typePermutation.getValue().getSelectedId() ) - { - - case 0://None->Identity - - { - cs_ipvec (n, nullptr, b.ptr(), x.ptr()) ; // copy - cs_lsolve (invertData->N->L, x.ptr() ) ; // x = L\x - cs_usolve (invertData->N->U, x.ptr() ) ; // x = U\x - break; - } - - case 1://SuiteSparse - { - cs_ipvec (n, invertData->N->Pinv, b.ptr(), invertData->tmp) ; // x = P*b , partial pivot - cs_lsolve (invertData->N->L, invertData->tmp) ; // x = L\x - cs_usolve (invertData->N->U, invertData->tmp) ; // x = U\x - cs_ipvec (n, invertData->S->Q, invertData->tmp, x.ptr()) ; // x = Q*x fill reducing permutation on columns only - break; - } - - case 2://METIS - { - // no partial pivoting - cs_pvec (n, invertData->perm.data() , b.ptr(), invertData->tmp) ; // x = P*b permutation on rows - cs_lsolve (invertData->N->L, invertData->tmp) ; // x = L\x - cs_usolve (invertData->N->U, invertData->tmp) ; // x = U\x - cs_pvec (n, invertData->iperm.data() , invertData->tmp , x.ptr()) ; // x = Q*x permutation on columns - break; - } - - default: - break; - } - } -} - -template -void SparseLUSolver::invert(Matrix& M) -{ - SparseLUInvertData * invertData = (SparseLUInvertData*) this->getMatrixInvertData(&M); - - sofa::linearalgebra::CompressedRowSparseMatrix* matrix; - - if constexpr (!std::is_same_v) - { - if (!Mfiltered) - { - Mfiltered = std::make_unique >(); - } - Mfiltered->copyNonZeros(M); - Mfiltered->compress(); - - matrix = Mfiltered.get(); - } - else - { - M.compress(); - matrix = &M; - } - - if (invertData->N) cs_nfree(invertData->N); - if (invertData->tmp) cs_free(invertData->tmp); - - //build A with M - invertData->A.nzmax = matrix->getColsValue().size(); // maximum number of entries - invertData->A.m = matrix->rowSize(); // number of rows - invertData->A.n = matrix->colSize(); // number of columns - invertData->A_p = matrix->getRowBegin(); - invertData->A.p = (int *) &(invertData->A_p[0]); // column pointers (size n+1) or col indices (size nzmax) - invertData->A_i = matrix->getColsIndex(); - invertData->A.i = (int *) &(invertData->A_i[0]); // row indices, size nzmax - invertData->A_x = matrix->getColsValue(); - invertData->A.x = (Real *) &(invertData->A_x[0]); // numerical values, size nzmax - invertData->A.nz = -1; // # of entries in triplet matrix, -1 for compressed-col - cs_dropzeros( &invertData->A ); - - invertData->notSameShape = compareMatrixShape(invertData->A.n , (int*) invertData->A_p.data() , (int*) invertData->A_i.data(), (invertData->Previous_colptr.size())-1 ,invertData->Previous_colptr.data() ,invertData->Previous_rowind.data() ); - - invertData->tmp = (Real *) cs_malloc (invertData->A.n, sizeof (Real)) ; - - { - SCOPED_TIMER_VARNAME(factorizationTimer, "factorization"); - switch( d_typePermutation.getValue().getSelectedId() ) - { - case 0://None->Identity - { - if (invertData->S) - { - cs_sfree(invertData->S); - } - invertData->S = symbolic_LU( &(invertData->A) ) ; // ordering and symbolic analysis - invertData->N = cs_lu (&invertData->A, invertData->S, f_tol.getValue()) ; // numeric LU factorization - break; - } - - case 1://SuiteSparse - { - if (invertData->notSameShape ) - { - if (invertData->S) - { - cs_sfree(invertData->S); - } - invertData->S = cs_sqr (&invertData->A, 1 , 0) ; // Suitsparse compute fill reducing permutation for LU decomposition - } - invertData->N = cs_lu (&invertData->A, invertData->S, f_tol.getValue()) ; // numeric LU factorization - break; - } - - case 2://Metis - { - if (invertData->notSameShape ) - { - invertData->perm.resize(invertData->A.n); - invertData->iperm.resize(invertData->A.n); - - fillReducingPermutation(invertData->A, invertData->perm.data(), invertData->iperm.data() ); //METIS compute the fill reducing permutation - } - - invertData->permuted_A = cs_permute(&(invertData->A), invertData->iperm.data(), invertData->perm.data(), 1); - - if (invertData->notSameShape ) - { - if (invertData->S) - { - cs_sfree(invertData->S); - } - invertData->S = symbolic_LU( invertData->permuted_A ); - } - - invertData->N = cs_lu ( invertData->permuted_A, invertData->S, f_tol.getValue()) ; // numeric LU factorization - - cs_free(invertData->permuted_A); // prevent memory leak - - break; - } - - default: - break; - } - } - - d_L_nnz.setValue(invertData->N->L->nzmax); - - // store the shape of the matrix - if ( invertData->notSameShape ) - { - invertData->Previous_rowind.clear(); - invertData->Previous_colptr.resize( (invertData->A.n) +1); - - for (int i=0 ; iA.n ; i++) - { - invertData->Previous_colptr[i+1] = invertData->A_p[i+1]; - - for ( int j = (int) invertData->A_p[i] ; j < (int)invertData->A_p[i+1] ; j++) - { - invertData->Previous_rowind.push_back( invertData->A_i[j]); - } - } - - } - -} - -template -css* SparseLUSolver::symbolic_LU(cs *A) -{// based on cs_sqr - - int n; - css *S ; - if (!A) return (NULL) ; /* check inputs */ - n = A->n ; - S = (css*)cs_calloc (1, sizeof (css)) ; /* allocate symbolic analysis */ - if (!S) return (NULL) ; /* out of memory */ - S->unz = 4*(A->p [n]) + n ; /* for LU factorization only, */ - S->lnz = S->unz ; /* guess nnz(L) and nnz(U) */ - S->Q = nullptr; // should have been the fill permutation computed by SuiteSparse, not used here - return S ; -} - -} // namespace sofa::component::linearsolver::direct +SOFA_PRAGMA_ERROR( \ + "This header has been DISABLED since v23.12. " \ + "To fix this error you must use the CSparseSolvers plugins. " ) diff --git a/Sofa/Component/LinearSolver/Preconditioner/src/sofa/component/linearsolver/preconditioner/PrecomputedWarpPreconditioner.h b/Sofa/Component/LinearSolver/Preconditioner/src/sofa/component/linearsolver/preconditioner/PrecomputedWarpPreconditioner.h index 9c71ecd0aa73..0ab268218b20 100644 --- a/Sofa/Component/LinearSolver/Preconditioner/src/sofa/component/linearsolver/preconditioner/PrecomputedWarpPreconditioner.h +++ b/Sofa/Component/LinearSolver/Preconditioner/src/sofa/component/linearsolver/preconditioner/PrecomputedWarpPreconditioner.h @@ -176,9 +176,7 @@ protected : PrecomputedWarpPreconditionerInternalData internalData; void rotateConstraints(); -#if SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE && !defined(SOFA_FLOAT) - void loadMatrixWithCSparse(TMatrix& M); -#endif + void loadMatrixWithCholeskyDecomposition(TMatrix& M); void loadMatrixWithSolver(); template diff --git a/Sofa/Component/LinearSolver/Preconditioner/src/sofa/component/linearsolver/preconditioner/PrecomputedWarpPreconditioner.inl b/Sofa/Component/LinearSolver/Preconditioner/src/sofa/component/linearsolver/preconditioner/PrecomputedWarpPreconditioner.inl index 5155ed3691f4..01627d1ace63 100644 --- a/Sofa/Component/LinearSolver/Preconditioner/src/sofa/component/linearsolver/preconditioner/PrecomputedWarpPreconditioner.inl +++ b/Sofa/Component/LinearSolver/Preconditioner/src/sofa/component/linearsolver/preconditioner/PrecomputedWarpPreconditioner.inl @@ -39,11 +39,8 @@ #include #include - -#if SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE && !defined(SOFA_FLOAT) -#include -#endif -#include +#include +#include #include @@ -184,13 +181,7 @@ void PrecomputedWarpPreconditioner::loadMatrix(TMatrix& M) msg_info() << "Precompute : " << fname << " compliance."; if (l_linearSolver.empty()) { -#if SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE && !defined(SOFA_FLOAT) - loadMatrixWithCSparse(M); -#else - msg_error() << "Link \"linearSolver\" is empty, but it is required to load matrix."; - this->d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid); - return; -#endif // SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE && !defined(SOFA_FLOAT) + loadMatrixWithCholeskyDecomposition(M); } else { @@ -222,9 +213,8 @@ void PrecomputedWarpPreconditioner::loadMatrix(TMatrix& M) } } -#if SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE && !defined(SOFA_FLOAT) template -void PrecomputedWarpPreconditioner::loadMatrixWithCSparse(TMatrix& M) +void PrecomputedWarpPreconditioner::loadMatrixWithCholeskyDecomposition(TMatrix& M) { msg_info() << "Compute the initial invert matrix with CS_PARSE" ; @@ -237,7 +227,7 @@ void PrecomputedWarpPreconditioner::loadMatrixWithCSparse(TMatrix& M b.resize(systemSize); for (unsigned int j=0; j, FullVector > solver; + direct::EigenSimplicialLLT solver; msg_info() << "Precomputing constraint correction LU decomposition " ; solver.invert(M); @@ -277,7 +267,6 @@ void PrecomputedWarpPreconditioner::loadMatrixWithCSparse(TMatrix& M tmpStr << "Precomputing constraint correction : " << std::fixed << 100.0f << " %" ; msg_info() << tmpStr.str(); } -#endif // SOFA_COMPONENT_LINEARSOLVER_DIRECT_HAVE_CSPARSE && !defined(SOFA_FLOAT) template void PrecomputedWarpPreconditioner::loadMatrixWithSolver() diff --git a/Sofa/framework/Core/src/sofa/core/topology/TopologyData.cpp b/Sofa/framework/Core/src/sofa/core/topology/TopologyData.cpp index ac1a0847a0c0..433fed3d6b8c 100644 --- a/Sofa/framework/Core/src/sofa/core/topology/TopologyData.cpp +++ b/Sofa/framework/Core/src/sofa/core/topology/TopologyData.cpp @@ -26,7 +26,7 @@ namespace sofa::core::topology { - + template class SOFA_CORE_API sofa::core::topology::TopologyData < core::topology::BaseMeshTopology::Point, type::vector >; } //namespace sofa::core::topology diff --git a/Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp b/Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp index b7958a4da16f..a3cb1196bed3 100644 --- a/Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp +++ b/Sofa/framework/Helper/src/sofa/helper/ComponentChange.cpp @@ -412,9 +412,7 @@ const std::map > uncreatableComponents // SofaSparseSolver was deprecated in #2717 { "FillReducingOrdering", Moved("v22.06", "SofaGeneralLinearSolver", "Sofa.Component.LinearSolver.Direct") }, { "PrecomputedLinearSolver", Moved("v22.06", "SofaGeneralLinearSolver", "Sofa.Component.LinearSolver.Direct") }, - { "SparseCholeskySolver", Moved("v22.06", "SofaSparseSolver", "Sofa.Component.LinearSolver.Direct") }, { "SparseLDLSolver", Moved("v22.06", "SofaSparseSolver", "Sofa.Component.LinearSolver.Direct") }, - { "SparseLUSolver", Moved("v22.06", "SofaSparseSolver", "Sofa.Component.LinearSolver.Direct") }, // SofaDenseSolver was deprecated in #2717 { "SVDLinearSolver", Moved("v22.06", "SofaDenseSolver", "Sofa.Component.LinearSolver.Direct") }, @@ -720,6 +718,10 @@ const std::map > uncreatableComponents // Removed in #4040, deprecated in #2777 { "MechanicalMatrixMapper", Removed("v23.06", "v23.12") }, { "MappingGeometricStiffnessForceField", Removed("v23.06", "v23.12") }, + + // Moved to CSparseSolvers + { "SparseCholeskySolver", Moved("v23.12", "Sofa.Component.LinearSolver.Direct", "CSparseSolvers") }, + { "SparseLUSolver", Moved("v23.12", "Sofa.Component.LinearSolver.Direct", "CSparseSolvers") }, }; } // namespace sofa::helper::lifecycle diff --git a/applications/plugins/CMakeLists.txt b/applications/plugins/CMakeLists.txt index 6d05efc15209..1e72b41f483d 100644 --- a/applications/plugins/CMakeLists.txt +++ b/applications/plugins/CMakeLists.txt @@ -51,6 +51,7 @@ sofa_add_subdirectory(plugin SoftRobots SoftRobots EXTERNAL) sofa_add_subdirectory(plugin CollisionAlgorithm CollisionAlgorithm EXTERNAL) sofa_add_subdirectory(plugin ConstraintGeometry ConstraintGeometry EXTERNAL) sofa_add_subdirectory(plugin ShapeMatchingPlugin ShapeMatchingPlugin EXTERNAL) +sofa_add_subdirectory(plugin CSparseSolvers CSparseSolvers EXTERNAL) sofa_add_subdirectory(plugin PSL PSL EXTERNAL) diff --git a/applications/plugins/CSparseSolvers/ExternalProjectConfig.cmake.in b/applications/plugins/CSparseSolvers/ExternalProjectConfig.cmake.in new file mode 100644 index 000000000000..989dbe703790 --- /dev/null +++ b/applications/plugins/CSparseSolvers/ExternalProjectConfig.cmake.in @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.11) + +include(ExternalProject) +ExternalProject_Add(CSparseSolvers + GIT_REPOSITORY https://github.com/sofa-framework/CSparseSolvers + GIT_TAG origin/master + SOURCE_DIR "${CMAKE_SOURCE_DIR}/applications/plugins/CSparseSolvers" + BINARY_DIR "" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" + GIT_CONFIG "remote.origin.fetch=+refs/pull/*:refs/remotes/origin/pr/*" +) diff --git a/applications/plugins/SofaCUDA/examples/beam10x10x46-warp-preconditioner-CUDA.scn b/applications/plugins/SofaCUDA/examples/beam10x10x46-warp-preconditioner-CUDA.scn index 169c19466eb9..50031644065e 100644 --- a/applications/plugins/SofaCUDA/examples/beam10x10x46-warp-preconditioner-CUDA.scn +++ b/applications/plugins/SofaCUDA/examples/beam10x10x46-warp-preconditioner-CUDA.scn @@ -32,7 +32,6 @@ - diff --git a/applications/plugins/SofaMatrix/examples/ComplianceMatrixExporter.scn b/applications/plugins/SofaMatrix/examples/ComplianceMatrixExporter.scn index d3eba819d21f..4949de493289 100644 --- a/applications/plugins/SofaMatrix/examples/ComplianceMatrixExporter.scn +++ b/applications/plugins/SofaMatrix/examples/ComplianceMatrixExporter.scn @@ -6,7 +6,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/applications/plugins/SofaMatrix/examples/ComplianceMatrixImage.scn b/applications/plugins/SofaMatrix/examples/ComplianceMatrixImage.scn index 98e93a04704d..d443ea930891 100644 --- a/applications/plugins/SofaMatrix/examples/ComplianceMatrixImage.scn +++ b/applications/plugins/SofaMatrix/examples/ComplianceMatrixImage.scn @@ -6,7 +6,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/applications/plugins/SofaMatrix/examples/FillReducingOrdering.scn b/applications/plugins/SofaMatrix/examples/FillReducingOrdering.scn index f1b20911242b..6e5f3c405283 100644 --- a/applications/plugins/SofaMatrix/examples/FillReducingOrdering.scn +++ b/applications/plugins/SofaMatrix/examples/FillReducingOrdering.scn @@ -10,7 +10,7 @@ The scene compares two simulations in which only the vertices order differs: - + @@ -33,7 +33,7 @@ The scene compares two simulations in which only the vertices order differs: - + @@ -49,7 +49,7 @@ The scene compares two simulations in which only the vertices order differs: - + diff --git a/examples/Component/Constraint/Lagrangian/InextensiblePendulum.scn b/examples/Component/Constraint/Lagrangian/InextensiblePendulum.scn index 939ff0feceae..ab6bdf1cb571 100644 --- a/examples/Component/Constraint/Lagrangian/InextensiblePendulum.scn +++ b/examples/Component/Constraint/Lagrangian/InextensiblePendulum.scn @@ -10,7 +10,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/examples/Component/LinearSolver/Direct/FEMBAR_SparseCholeskySolver.scn b/examples/Component/LinearSolver/Direct/FEMBAR_SparseCholeskySolver.scn deleted file mode 100644 index a9e826a29567..000000000000 --- a/examples/Component/LinearSolver/Direct/FEMBAR_SparseCholeskySolver.scn +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/examples/Component/LinearSolver/Direct/FEMBAR_SparseLUSolver.scn b/examples/Component/LinearSolver/Direct/FEMBAR_SparseLUSolver.scn deleted file mode 100644 index 241b8fb05d3a..000000000000 --- a/examples/Component/LinearSolver/Direct/FEMBAR_SparseLUSolver.scn +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/examples/Component/Mapping/NonLinear/DistanceFromTargetMapping.scn b/examples/Component/Mapping/NonLinear/DistanceFromTargetMapping.scn index 0a2144bea18b..1dd85728358a 100644 --- a/examples/Component/Mapping/NonLinear/DistanceFromTargetMapping.scn +++ b/examples/Component/Mapping/NonLinear/DistanceFromTargetMapping.scn @@ -1,7 +1,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/examples/Component/SolidMechanics/FEM/RestShapeSpringsForceField3.scn b/examples/Component/SolidMechanics/FEM/RestShapeSpringsForceField3.scn index b76804847503..6b034813594b 100644 --- a/examples/Component/SolidMechanics/FEM/RestShapeSpringsForceField3.scn +++ b/examples/Component/SolidMechanics/FEM/RestShapeSpringsForceField3.scn @@ -5,7 +5,7 @@ - + @@ -21,7 +21,7 @@ - + - + @@ -23,7 +23,7 @@ - + diff --git a/examples/RegressionStateScenes.regression-tests b/examples/RegressionStateScenes.regression-tests index f430b475ae69..7ac5834edf8d 100644 --- a/examples/RegressionStateScenes.regression-tests +++ b/examples/RegressionStateScenes.regression-tests @@ -33,9 +33,7 @@ Component/LinearSolver/Direct/FEMBAR_EigenSimplicialLLT.scn 100 1e-8 0 1 Component/LinearSolver/Direct/FEMBAR_EigenSparseLU.scn 100 1e-8 0 1 Component/LinearSolver/Direct/FEMBAR_EigenSparseQR.scn 100 1e-8 0 1 Component/LinearSolver/Direct/FEMBAR_PrecomputedLinearSolver.scn 100 1e-8 0 1 -Component/LinearSolver/Direct/FEMBAR_SparseCholeskySolver.scn 100 1e-8 0 1 Component/LinearSolver/Direct/FEMBAR_SparseLDLSolver.scn 100 1e-8 0 1 -Component/LinearSolver/Direct/FEMBAR_SparseLUSolver.scn 100 1e-8 0 1 Component/LinearSolver/Iterative/FEMBAR_MinResLinearSolver.scn 100 1e-8 0 1 Component/LinearSolver/Iterative/FEMBAR_ShewchukPCGLinearSolver.scn 1e-8 0 1 Component/LinearSolver/Iterative/FEMBAR_CGLinearSolver.scn 100 1e-8 0 1 From c3aa7d31c165d5b51daa7f4b95e8724aee2c1021 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Fri, 24 Nov 2023 17:47:57 +0100 Subject: [PATCH 39/60] [GUI.Qt] Minor single-line cleaning (#4308) Co-authored-by: erik pernod --- Sofa/GUI/Qt/src/sofa/gui/qt/RealGUI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/RealGUI.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/RealGUI.cpp index 442d20d86eae..1f4b1d27d7b4 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/RealGUI.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/RealGUI.cpp @@ -1180,7 +1180,7 @@ void RealGUI::registerViewer(BaseViewer* _viewer) BaseViewer* RealGUI::getViewer() { - return m_viewer!=nullptr ? m_viewer : nullptr; + return m_viewer; } //------------------------------------ From 060227166211c7459e8216d17b9e35ee70247aa7 Mon Sep 17 00:00:00 2001 From: Olivier Roussel Date: Wed, 29 Nov 2023 11:28:04 +0100 Subject: [PATCH 40/60] [Sofa.GUI.Qt] Add cmake module for QGLViewer (#4290) * Add cmake module for QGLViewer * Support library name for apt packages * Fix qglviewer cmake finder module to first seach for a config cmake file. * Update cmake/Modules/FindQGLViewer.cmake Co-authored-by: Hugo --------- Co-authored-by: Frederick Roy Co-authored-by: Hugo --- Sofa/GUI/Qt/CMakeLists.txt | 2 +- cmake/Modules/FindQGLViewer.cmake | 69 +++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 cmake/Modules/FindQGLViewer.cmake diff --git a/Sofa/GUI/Qt/CMakeLists.txt b/Sofa/GUI/Qt/CMakeLists.txt index 56256c3694dc..8de94a80a939 100644 --- a/Sofa/GUI/Qt/CMakeLists.txt +++ b/Sofa/GUI/Qt/CMakeLists.txt @@ -74,7 +74,7 @@ if(Sofa.GL_FOUND) option(SOFA_GUI_QT_ENABLE_QGLVIEWER "Compile the QGLViewer for the Qt GUI" ON) if(SOFA_GUI_QT_ENABLE_QGLVIEWER) - find_package(QGLViewer QUIET) + find_package(QGLViewer) if(NOT QGLViewer_FOUND) add_subdirectory(libQGLViewer/QGLViewer) endif() diff --git a/cmake/Modules/FindQGLViewer.cmake b/cmake/Modules/FindQGLViewer.cmake new file mode 100644 index 000000000000..cbf284d949af --- /dev/null +++ b/cmake/Modules/FindQGLViewer.cmake @@ -0,0 +1,69 @@ +# Find the QGLViewer headers and libraries +# Behavior is to first look for config files. +# If no config files were found, tries to find +# the library by looking at headers / lib file. +# +# Defines: +# QGLViewer_FOUND : True if QGLViewer is found +# +# Provides target QGLViewer. + +find_package(QGLViewer NO_MODULE QUIET) + +if(NOT TARGET QGLViewer) + + if(NOT QGLViewer_INCLUDE_DIR) + find_path(QGLViewer_INCLUDE_DIR + NAMES qglviewer.h + PATH_SUFFIXES include/QGLViewer + ) + endif() + + if(NOT QGLViewer_LIBRARY) + find_library(QGLViewer_LIBRARY + NAMES QGLViewer QGLViewer-qt5 + PATH_SUFFIXES lib + ) + endif() + + if(QGLViewer_INCLUDE_DIR AND QGLViewer_LIBRARY) + set(QGLViewer_FOUND TRUE) + else() + if(QGLViewer_FIND_REQUIRED) + message(FATAL_ERROR "Cannot find QGLViewer") + endif() + endif() + + # Same checks as Sofa.GUI.Qt + # i.e find Qt5, then if not, Qt6, then if not error + find_package(Qt5 COMPONENTS Core QUIET) + if (NOT Qt5Core_FOUND) + if(${CMAKE_VERSION} VERSION_GREATER "3.16.0") + find_package(Qt6 COMPONENTS Core CoreTools QUIET) + endif() + endif() + + if (Qt5Core_FOUND) + find_package(Qt5 COMPONENTS Core Charts Gui Xml OpenGL Widgets REQUIRED) + set(QT_TARGETS Qt5::Core Qt5::Charts Qt5::Gui Qt5::Xml Qt5::OpenGL Qt5::Widgets) + elseif (Qt6Core_FOUND) + find_package(Qt6 COMPONENTS Gui Charts GuiTools Widgets WidgetsTools OpenGLWidgets Xml REQUIRED) + set(QT_TARGETS ${QT_TARGETS} Qt::Core Qt::Charts Qt::Gui Qt::Widgets Qt::OpenGLWidgets Qt::Xml) + endif() + + if(QGLViewer_FOUND) + set(QGLViewer_LIBRARIES ${QGLViewer_LIBRARY}) + set(QGLViewer_INCLUDE_DIRS ${QGLViewer_INCLUDE_DIR}) + + if(NOT QGLViewer_FIND_QUIETLY) + message(STATUS "Found QGLViewer: ${QGLVIEWER_LIBRARIES}") + endif(NOT QGLViewer_FIND_QUIETLY) + + if(NOT TARGET QGLViewer) + add_library(QGLViewer INTERFACE IMPORTED) + set_property(TARGET QGLViewer PROPERTY INTERFACE_LINK_LIBRARIES "${QGLViewer_LIBRARIES}" ${QT_TARGETS}) + set_property(TARGET QGLViewer PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${QGLViewer_INCLUDE_DIR}") + endif() + endif() + mark_as_advanced(QGLViewer_INCLUDE_DIR QGLViewer_LIBRARY) +endif() From 8e1dca008f09d7147196c57513655f2477c47d37 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 29 Nov 2023 11:30:14 +0100 Subject: [PATCH 41/60] [MultiThreading] Avoid Static Initialization Order Fiasco (#4307) --- .../ParallelImplementationsRegistry.cpp | 16 ++++++++++------ .../ParallelImplementationsRegistry.h | 1 - 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/applications/plugins/MultiThreading/src/MultiThreading/ParallelImplementationsRegistry.cpp b/applications/plugins/MultiThreading/src/MultiThreading/ParallelImplementationsRegistry.cpp index e201063e0137..78e33a5bb23f 100644 --- a/applications/plugins/MultiThreading/src/MultiThreading/ParallelImplementationsRegistry.cpp +++ b/applications/plugins/MultiThreading/src/MultiThreading/ParallelImplementationsRegistry.cpp @@ -25,7 +25,11 @@ namespace multithreading { -sofa::type::vector ParallelImplementationsRegistry::s_implementations; +sofa::type::vector& getStaticImplementations() +{ + static sofa::type::vector s_implementations; + return s_implementations; +} bool ParallelImplementationsRegistry::addEquivalentImplementations( const std::string& sequentialImplementation, const std::string& parallelImplementation) @@ -34,9 +38,9 @@ bool ParallelImplementationsRegistry::addEquivalentImplementations( const auto it = findParallelImplementationImpl(sequentialImplementation); - if (it == s_implementations.end()) + if (it == getStaticImplementations().end()) { - s_implementations.push_back(implementation); + getStaticImplementations().push_back(implementation); return true; } @@ -62,7 +66,7 @@ std::string ParallelImplementationsRegistry::findParallelImplementation( { const auto it = findParallelImplementationImpl(sequentialImplementation); - if (it != s_implementations.end()) + if (it != getImplementations().end()) { return it->parallel; } @@ -72,14 +76,14 @@ std::string ParallelImplementationsRegistry::findParallelImplementation( const sofa::type::vector& ParallelImplementationsRegistry::getImplementations() { - return s_implementations; + return getStaticImplementations(); } sofa::type::vector::const_iterator ParallelImplementationsRegistry::findParallelImplementationImpl( const std::string& sequentialImplementation) { - return std::find_if(s_implementations.begin(), s_implementations.end(), + return std::find_if(getStaticImplementations().begin(), getStaticImplementations().end(), [&sequentialImplementation](const Implementation& i) { return i.sequential == sequentialImplementation; diff --git a/applications/plugins/MultiThreading/src/MultiThreading/ParallelImplementationsRegistry.h b/applications/plugins/MultiThreading/src/MultiThreading/ParallelImplementationsRegistry.h index 37cd573edb74..f7c6d90ee0b7 100644 --- a/applications/plugins/MultiThreading/src/MultiThreading/ParallelImplementationsRegistry.h +++ b/applications/plugins/MultiThreading/src/MultiThreading/ParallelImplementationsRegistry.h @@ -44,7 +44,6 @@ class SOFA_MULTITHREADING_PLUGIN_API ParallelImplementationsRegistry static const sofa::type::vector& getImplementations(); private: - static sofa::type::vector s_implementations; static sofa::type::vector::const_iterator findParallelImplementationImpl(const std::string& sequentialImplementation); }; From 49d4c2ead895bfb2d89aa0eda3a58fcfb073d91f Mon Sep 17 00:00:00 2001 From: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Wed, 29 Nov 2023 11:31:37 +0100 Subject: [PATCH 42/60] [Core] Minor clean of DefaultAnimationLoop (#4314) * Remove unlogical use of visitor * Delete unused methods --- .../sofa/simulation/DefaultAnimationLoop.cpp | 19 ------------------- .../sofa/simulation/DefaultAnimationLoop.h | 2 -- 2 files changed, 21 deletions(-) diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp index 1673a6940d91..0bf53d191c82 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp @@ -170,14 +170,6 @@ void DefaultAnimationLoop::propagateAnimateBeginEvent(const core::ExecParams* pa m_node->execute(act); } -void DefaultAnimationLoop::resetConstraint(const core::ExecParams* params) const -{ - SCOPED_TIMER("resetConstraint"); - const sofa::core::ConstraintParams cparams(*params); - sofa::simulation::mechanicalvisitor::MechanicalResetConstraintVisitor resetConstraint(&cparams); - m_node->execute(&resetConstraint); -} - void DefaultAnimationLoop::beginIntegration(const core::ExecParams* params, SReal dt) const { propagateIntegrateBeginEvent(params); @@ -195,14 +187,6 @@ void DefaultAnimationLoop::propagateIntegrateBeginEvent(const core::ExecParams* eventPropagation.execute(m_node); } -void DefaultAnimationLoop::buildConstraintMatrix(core::ConstraintParams cparams) const -{ - SCOPED_TIMER("buildConstraintMatrix"); - unsigned int constraintId = 0; - mechanicalvisitor::MechanicalBuildConstraintMatrix buildConstraintMatrix(&cparams, core::MatrixDerivId::constraintJacobian(), constraintId ); - buildConstraintMatrix.execute(m_node); -} - void DefaultAnimationLoop::accumulateMatrixDeriv(const core::ConstraintParams cparams) const { SCOPED_TIMER("accumulateMatrixDeriv"); @@ -292,14 +276,11 @@ void DefaultAnimationLoop::animate(const core::ExecParams* params, SReal dt) con behaviorUpdatePosition(params, dt); updateInternalData(params); - resetConstraint(params); - collisionDetection(params); beginIntegration(params, dt); { const core::ConstraintParams cparams; - buildConstraintMatrix(cparams); accumulateMatrixDeriv(cparams); solve(params, dt); diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.h index dff897be4856..c11161170f08 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.h @@ -69,10 +69,8 @@ protected : void behaviorUpdatePosition(const sofa::core::ExecParams* params, SReal dt) const; void updateInternalData(const sofa::core::ExecParams* params) const; - void resetConstraint(const sofa::core::ExecParams* params) const; void beginIntegration(const sofa::core::ExecParams* params, SReal dt) const; void propagateIntegrateBeginEvent(const sofa::core::ExecParams* params) const; - void buildConstraintMatrix(sofa::core::ConstraintParams cparams) const; void accumulateMatrixDeriv(sofa::core::ConstraintParams cparams) const; void solve(const sofa::core::ExecParams* params, SReal dt) const; void propagateIntegrateEndEvent(const sofa::core::ExecParams* params) const; From bd72b87d8f5f2fdaf0540d8a34d1910ab18849e3 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 29 Nov 2023 11:32:03 +0100 Subject: [PATCH 43/60] [LinearSystem] Speedup computation of Jacobian matrices (#4317) * [LinearSystem] Speedup computation of Jacobian matrices in case both mstates are the same * minor reformat to align calls to computeJacobiansFrom --- .../component/linearsystem/MatrixLinearSystem.inl | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl index 54964cd34fa7..18231191cb68 100644 --- a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/MatrixLinearSystem.inl @@ -988,7 +988,8 @@ void MatrixLinearSystem::projectMappedMatrices(const core::Mec } const MappingJacobians J0 = computeJacobiansFrom(pair[0], mparams, crs); - const MappingJacobians J1 = computeJacobiansFrom(pair[1], mparams, crs); + const MappingJacobians J1 = + (pair[0] == pair[1]) ? J0 : computeJacobiansFrom(pair[1], mparams, crs); const sofa::type::fixed_array, 2> mappingMatricesMap { J0, J1 }; @@ -1039,6 +1040,10 @@ auto MatrixLinearSystem::computeJacobiansFrom(BaseMechanicalSt auto mappingJacobianId = sofa::core::MatrixDerivId::mappingJacobian(); + // optimisation to build only the relevent entries of the jacobian matrices + // The relevent entries are the ones that have a influence on the result + // of the product J^T * K * J. + // J does not need to be fully computed if K is sparse. { const std::vector listAffectedDoFs = identifyAffectedDoFs(mstate, crs); @@ -1049,12 +1054,17 @@ auto MatrixLinearSystem::computeJacobiansFrom(BaseMechanicalSt mstate->buildIdentityBlocksInJacobian(listAffectedDoFs, mappingJacobianId); } + // apply the mappings from the bottom to the top, so it builds the jacobian + // matrices, transforming the space from the input DoFs to the space of the + // top most DoFs const auto parentMappings = getMappingGraph().getBottomUpMappingsFrom(mstate); for (auto* mapping : parentMappings) { mapping->applyJT(&cparams, mappingJacobianId, mappingJacobianId); } + // copy the jacobian matrix stored in the mechanical states into a local + // matrix data structure const auto inputs = m_mappingGraph.getTopMostMechanicalStates(mstate); for (auto* input : inputs) { @@ -1062,7 +1072,7 @@ auto MatrixLinearSystem::computeJacobiansFrom(BaseMechanicalSt jacobians.addJacobianToTopMostParent(J, input); J->resize(mstate->getMatrixSize(), input->getMatrixSize()); unsigned int offset {}; - input->copyToBaseMatrix(J.get(), sofa::core::MatrixDerivId::mappingJacobian(), offset); + input->copyToBaseMatrix(J.get(), mappingJacobianId, offset); J->fullRows(); } From d0ebf664e516d6b16fe3e265e0e700c8ee2a46ee Mon Sep 17 00:00:00 2001 From: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Wed, 29 Nov 2023 11:32:25 +0100 Subject: [PATCH 44/60] [SofaCUDA] FIX compilation SofaCUDA along with SparseGrid with Cuda12 (#4319) * FIX compilation SofaCUDA along with SparseGrid with Cuda12 * Use a multiplication instead --- .../plugins/SofaCUDA/sofa/gpu/cuda/CudaContactMapper.cu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaContactMapper.cu b/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaContactMapper.cu index 80f8aefc7375..a8e6be42025e 100644 --- a/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaContactMapper.cu +++ b/applications/plugins/SofaCUDA/sofa/gpu/cuda/CudaContactMapper.cu @@ -85,7 +85,7 @@ __global__ void SubsetContactMapperCuda3f_setPoints1_kernel(unsigned int nbPoint GPUContact c = contacts[curTestEntry.firstIndex + threadIdx.x]; if (threadIdx.x < curTestEntry.curSize) { - map[curTestEntry.newIndex + threadIdx.x] = umul24(curTestEntry.elem1,nbPointsPerElem) + c.p1; + map[curTestEntry.newIndex + threadIdx.x] = curTestEntry.elem1 * nbPointsPerElem + c.p1; } } From 4f14815ee02d128d982770df623a48bca0afe789 Mon Sep 17 00:00:00 2001 From: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Wed, 29 Nov 2023 11:34:25 +0100 Subject: [PATCH 45/60] [Common] Add message to make the fetch mechanism less hidden (#4310) * Add message to make it more clear * slight modifications to be even more clear and add an error the dependency cannot be met --- Sofa/GUI/Common/CMakeLists.txt | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/Sofa/GUI/Common/CMakeLists.txt b/Sofa/GUI/Common/CMakeLists.txt index b1eb06b7d1f1..f6cb2e6dd63e 100644 --- a/Sofa/GUI/Common/CMakeLists.txt +++ b/Sofa/GUI/Common/CMakeLists.txt @@ -1,24 +1,29 @@ cmake_minimum_required(VERSION 3.12) project(Sofa.GUI.Common LANGUAGES CXX) -find_package(cxxopts 3.1) +find_package(cxxopts 3.1 QUIET) if(NOT cxxopts_FOUND AND SOFA_ALLOW_FETCH_DEPENDENCIES) - include(FetchContent) - FetchContent_Declare(cxxopts - GIT_REPOSITORY https://github.com/jarro2783/cxxopts - GIT_TAG v3.1.1 - ) + message("Sofa.GUI.Common: DEPENDENCY cxxopt NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is ON, fetching cxxopt...") - FetchContent_GetProperties(cxxopts) - if(NOT cxxopts_POPULATED) - FetchContent_Populate(cxxopts) + include(FetchContent) + FetchContent_Declare(cxxopts + GIT_REPOSITORY https://github.com/jarro2783/cxxopts + GIT_TAG v3.1.1 + ) + + FetchContent_GetProperties(cxxopts) + if(NOT cxxopts_POPULATED) + FetchContent_Populate(cxxopts) - set(CXXOPTS_BUILD_EXAMPLES OFF CACHE INTERNAL "") - set(CXXOPTS_BUILD_TESTS OFF CACHE INTERNAL "") - set(CXXOPTS_ENABLE_INSTALL ON CACHE INTERNAL "") + set(CXXOPTS_BUILD_EXAMPLES OFF CACHE INTERNAL "") + set(CXXOPTS_BUILD_TESTS OFF CACHE INTERNAL "") + set(CXXOPTS_ENABLE_INSTALL ON CACHE INTERNAL "") + message("Sofa.GUI.Common: adding subdirectory ${cxxopts_SOURCE_DIR}") - add_subdirectory(${cxxopts_SOURCE_DIR} ${cxxopts_BINARY_DIR}) - endif() + add_subdirectory(${cxxopts_SOURCE_DIR} ${cxxopts_BINARY_DIR}) + endif() +elseif (NOT cxxopts_FOUND) + message(FATAL_ERROR "Sofa.GUI.Common: DEPENDENCY cxxopt NOT FOUND. SOFA_ALLOW_FETCH_DEPENDENCIES is OFF and thus cannot be fetched. Install libcxxopts-dev (version>=3.1.0), or enable SOFA_ALLOW_FETCH_DEPENDENCIES to fix this issue.") endif() set(SOFAGUICOMMON_ROOT src/sofa/gui/common) From 452b2a9bdd6dd04b6ecd930a5840efcc65db7f94 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Wed, 29 Nov 2023 19:51:01 +0900 Subject: [PATCH 46/60] [Collections] Remove reference to non-existing SofaSimulation (#4320) remove ref to non-existent sofasimu Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --- applications/collections/deprecated/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/applications/collections/deprecated/CMakeLists.txt b/applications/collections/deprecated/CMakeLists.txt index 4b7271178193..f8ae3ddeb9bb 100644 --- a/applications/collections/deprecated/CMakeLists.txt +++ b/applications/collections/deprecated/CMakeLists.txt @@ -1,7 +1,6 @@ # meta-modules (SofaKernel) sofa_add_subdirectory(collection SofaFramework SofaFramework ON WHEN_TO_SHOW "SOFA_ENABLE_LEGACY_HEADERS" VALUE_IF_HIDDEN OFF) -sofa_add_subdirectory(collection SofaSimulation SofaSimulation ON WHEN_TO_SHOW "SOFA_ENABLE_LEGACY_HEADERS" VALUE_IF_HIDDEN OFF) sofa_add_subdirectory(collection SofaBase SofaBase ON WHEN_TO_SHOW "SOFA_ENABLE_LEGACY_HEADERS" VALUE_IF_HIDDEN OFF) From bc6c9dbe377a44da514f151818a6af6fce83282d Mon Sep 17 00:00:00 2001 From: Paul Baksic <30337881+bakpaul@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:07:45 +0100 Subject: [PATCH 47/60] [All] Changed default plugins (#4322) Changed default plugins --- applications/plugins/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/plugins/CMakeLists.txt b/applications/plugins/CMakeLists.txt index 1e72b41f483d..ba0a49e6d0fb 100644 --- a/applications/plugins/CMakeLists.txt +++ b/applications/plugins/CMakeLists.txt @@ -11,13 +11,13 @@ sofa_add_subdirectory(plugin CollisionOBBCapsule CollisionOBBCapsule) sofa_add_subdirectory(directory SofaHighOrder SofaHighOrder EXTERNAL) -sofa_add_subdirectory(plugin CImgPlugin CImgPlugin ON) # ON by default and first as it is used by other plugins. +sofa_add_subdirectory(plugin CImgPlugin CImgPlugin) # ON by default and first as it is used by other plugins. sofa_add_subdirectory(plugin ArticulatedSystemPlugin ArticulatedSystemPlugin ON) sofa_add_subdirectory(plugin SofaEulerianFluid SofaEulerianFluid) sofa_add_subdirectory(plugin SofaSphFluid SofaSphFluid) sofa_add_subdirectory(plugin SofaDistanceGrid SofaDistanceGrid) # Depends on SofaMiscCollision sofa_add_subdirectory(plugin SofaImplicitField SofaImplicitField) -sofa_add_subdirectory(plugin MultiThreading MultiThreading) +sofa_add_subdirectory(plugin MultiThreading MultiThreading ON) sofa_add_subdirectory(plugin DiffusionSolver DiffusionSolver) # Depends on CImgPlugin sofa_add_subdirectory(plugin image image) # Depends on CImgPlugin, DiffusionSolver, MultiThreading (soft) sofa_add_subdirectory(plugin SofaNewmat SofaNewmat) From 3e4ec13eddebe9127165eabc840e724c371dfc25 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Thu, 30 Nov 2023 22:28:51 +0100 Subject: [PATCH 48/60] [SolidMechanics.Spring] Implement buildStiffnessMatrix for TriangularBendingSprings (#4295) Co-authored-by: Hugo --- .../spring/TriangularBendingSprings.h | 1 + .../spring/TriangularBendingSprings.inl | 30 +++++++++++- .../Spring/TriangularBendingSprings.scn | 48 ++++++++----------- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.h index 1c4a57cea868..6b37f9cbfc94 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.h @@ -139,6 +139,7 @@ class TriangularBendingSprings : public core::behavior::ForceField void addForce(const core::MechanicalParams* mparams, DataVecDeriv& d_f, const DataVecCoord& d_x, const DataVecDeriv& d_v) override; void addDForce(const core::MechanicalParams* mparams, DataVecDeriv& d_df, const DataVecDeriv& d_dx) override; + void buildStiffnessMatrix(core::behavior::StiffnessMatrix* matrix) override; void buildDampingMatrix(core::behavior::DampingMatrix* /*matrix*/) final; void draw(const core::visual::VisualParams* vparams) override; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.inl index 90d04039e56c..fd9f38232c25 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/TriangularBendingSprings.inl @@ -502,7 +502,7 @@ void TriangularBendingSprings::addForce(const core::MechanicalParams* template void TriangularBendingSprings::addDForce(const core::MechanicalParams* mparams, DataVecDeriv& d_df, const DataVecDeriv& d_dx) { - VecDeriv& df = *d_df.beginEdit(); + auto df = sofa::helper::getWriteAccessor(d_df); const VecDeriv& dx = d_dx.getValue(); Real kFactor = (Real)sofa::core::mechanicalparams::kFactorIncludingRayleighDamping(mparams, this->rayleighStiffness.getValue()); @@ -524,7 +524,33 @@ void TriangularBendingSprings::addDForce(const core::MechanicalParams df[a]+= dforce * kFactor; df[b]-= dforce * kFactor; } - d_df.endEdit(); +} + +template +void TriangularBendingSprings::buildStiffnessMatrix( + core::behavior::StiffnessMatrix* matrix) +{ + auto dfdx = matrix->getForceDerivativeIn(this->mstate) + .withRespectToPositionsIn(this->mstate); + + const type::vector& edgeInf = edgeInfo.getValue(); + + for (sofa::Index i = 0; i < m_topology->getNbEdges(); i++) + { + const EdgeInformation& einfo = edgeInf[i]; + if (einfo.is_activated) // edge not in middle of 2 triangles + { + const sofa::Index a = Deriv::total_size * einfo.m1; + const sofa::Index b = Deriv::total_size * einfo.m2; + + const Mat& dfdxLocal = einfo.DfDx; + + dfdx(a, a) += -dfdxLocal; + dfdx(a, b) += dfdxLocal; + dfdx(b, a) += dfdxLocal; + dfdx(b, b) += -dfdxLocal; + } + } } template diff --git a/examples/Component/SolidMechanics/Spring/TriangularBendingSprings.scn b/examples/Component/SolidMechanics/Spring/TriangularBendingSprings.scn index 608bfc799ed7..1b7c86c30004 100644 --- a/examples/Component/SolidMechanics/Spring/TriangularBendingSprings.scn +++ b/examples/Component/SolidMechanics/Spring/TriangularBendingSprings.scn @@ -1,43 +1,37 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - + - + + - + - - - + + From 4ecb558f19811320881916aa756f3fb2d65c49f9 Mon Sep 17 00:00:00 2001 From: Hugo Date: Fri, 1 Dec 2023 17:27:17 +0100 Subject: [PATCH 49/60] [all] Fix warnings (#4291) * [all] Fix warnings * revert change on scenes wrongly committed * Apply suggestions from code review Co-authored-by: Alex Bilger * [all] Fix warnings * Fix runtime error due to useless destructor * take reviews into account: d_nbThreads back to int --------- Co-authored-by: Alex Bilger --- .../tests/FixedPlaneConstraint_test.cpp | 2 +- .../iterative/MatrixLinearSolver.inl | 8 +- .../matrixaccumulators/ConstantLocalMatrix.h | 4 + .../tests/MatrixLinearSystem_test.cpp | 36 ++++- .../mechanicalload/EllipsoidForceField.h | 46 ++---- .../mechanicalload/EllipsoidForceField.inl | 10 +- .../sofa/component/mechanicalload/config.h.in | 6 +- .../elastic/TriangularFEMForceFieldOptim.inl | 2 - .../CompressedRowSparseMatrixGeneric.h | 2 +- .../sofa/simulation/DefaultAnimationLoop.cpp | 1 + .../DefaultCollisionGroupManager_test.cpp | 10 +- .../SofaValidation_test/Monitor_test.cpp | 2 +- .../examples/benchmark_cubes.scn | 144 +++++++++--------- .../src/MultiThreading/TaskSchedulerUser.cpp | 2 +- ...allelCompressedRowSparseMatrixMechanical.h | 8 +- .../examples/SimpleBox-Method2.scn | 2 +- .../image/image_test/ImageEngine_test.cpp | 14 +- .../SofaPhysicsAPI/SofaPhysicsBindings.cpp | 2 +- .../tutorials/chainHybrid/chainHybrid.cpp | 3 +- .../compositeObject/compositeObject.cpp | 6 +- .../tutorials/mixedPendulum/mixedPendulum.cpp | 6 +- .../tutorials/oneParticle/oneParticle.cpp | 3 +- 22 files changed, 163 insertions(+), 156 deletions(-) diff --git a/Sofa/Component/Constraint/Projective/tests/FixedPlaneConstraint_test.cpp b/Sofa/Component/Constraint/Projective/tests/FixedPlaneConstraint_test.cpp index 5ed1c9ca8555..b040bfced844 100644 --- a/Sofa/Component/Constraint/Projective/tests/FixedPlaneConstraint_test.cpp +++ b/Sofa/Component/Constraint/Projective/tests/FixedPlaneConstraint_test.cpp @@ -67,7 +67,7 @@ struct FixedPlaneConstraint_test : public BaseSimulationTest /// Scene initialization sofa::simulation::Simulation* simulation; - sofa::simulation::setSimulation(simulation = new sofa::simulation::graph::DAGSimulation()); + simulation = sofa::simulation::getSimulation(); simulation::Node::SPtr root = simulation->createNewGraph("root"); root->setGravity( type::Vec3(0,0,0) ); diff --git a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.inl b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.inl index e4e87e3b3557..39297dbb0673 100644 --- a/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.inl +++ b/Sofa/Component/LinearSolver/Iterative/src/sofa/component/linearsolver/iterative/MatrixLinearSolver.inl @@ -45,14 +45,14 @@ using namespace sofa::component::linearsystem; template MatrixLinearSolver::MatrixLinearSolver() : Inherit() + , d_parallelInverseProduct(initData(&d_parallelInverseProduct, false, + "parallelInverseProduct", "Parallelize the computation of the product J*M^{-1}*J^T " + "where M is the matrix of the linear system and J is any " + "matrix with compatible dimensions")) , invertData() , linearSystem() , currentMFactor(), currentBFactor(), currentKFactor() , l_linearSystem(initLink("linearSystem", "The linear system to solve")) - , d_parallelInverseProduct(initData(&d_parallelInverseProduct, false, - "parallelInverseProduct", "Parallelize the computation of the product J*M^{-1}*J^T " - "where M is the matrix of the linear system and J is any " - "matrix with compatible dimensions")) { this->addUpdateCallback("parallelInverseProduct", {&d_parallelInverseProduct}, [this](const core::DataTracker& tracker) -> sofa::core::objectmodel::ComponentState diff --git a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMatrix.h b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMatrix.h index cdb9a88978cc..4442e1bd00d7 100644 --- a/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMatrix.h +++ b/Sofa/Component/LinearSystem/src/sofa/component/linearsystem/matrixaccumulators/ConstantLocalMatrix.h @@ -52,6 +52,8 @@ class ConstantLocalMatrix : public virtual AssemblingMatrixAccumulator template void ConstantLocalMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, float value) { + SOFA_UNUSED(row); + SOFA_UNUSED(col); static_cast(this->m_globalMatrix)->colsValue[insertionOrderList[currentId++]] += this->m_cachedFactor * value; } @@ -59,6 +61,8 @@ void ConstantLocalMatrix::add(const core::matrixaccumulator::no_chec template void ConstantLocalMatrix::add(const core::matrixaccumulator::no_check_policy&, sofa::SignedIndex row, sofa::SignedIndex col, double value) { + SOFA_UNUSED(row); + SOFA_UNUSED(col); static_cast(this->m_globalMatrix)->colsValue[insertionOrderList[currentId++]] += this->m_cachedFactor * value; } diff --git a/Sofa/Component/LinearSystem/tests/MatrixLinearSystem_test.cpp b/Sofa/Component/LinearSystem/tests/MatrixLinearSystem_test.cpp index a1e0825af215..bf951a8e1826 100644 --- a/Sofa/Component/LinearSystem/tests/MatrixLinearSystem_test.cpp +++ b/Sofa/Component/LinearSystem/tests/MatrixLinearSystem_test.cpp @@ -250,9 +250,23 @@ template dfdx(10, 20) += 0.; } - void addForce(const sofa::core::MechanicalParams*, typename Inherit1::DataVecDeriv& f, const typename Inherit1::DataVecCoord& x, const typename Inherit1::DataVecDeriv& v) override {} - void addDForce(const sofa::core::MechanicalParams* mparams, typename Inherit1::DataVecDeriv& df, const typename Inherit1::DataVecDeriv& dx ) override {} - SReal getPotentialEnergy(const sofa::core::MechanicalParams*, const typename Inherit1::DataVecCoord& x) const override { return 0._sreal; } + void addForce(const sofa::core::MechanicalParams*, typename Inherit1::DataVecDeriv& f, const typename Inherit1::DataVecCoord& x, const typename Inherit1::DataVecDeriv& v) override + { + SOFA_UNUSED(f); + SOFA_UNUSED(x); + SOFA_UNUSED(v); + } + void addDForce(const sofa::core::MechanicalParams* mparams, typename Inherit1::DataVecDeriv& df, const typename Inherit1::DataVecDeriv& dx ) override + { + SOFA_UNUSED(mparams); + SOFA_UNUSED(df); + SOFA_UNUSED(dx); + } + SReal getPotentialEnergy(const sofa::core::MechanicalParams*, const typename Inherit1::DataVecCoord& x) const override + { + SOFA_UNUSED(x); + return 0._sreal; + } }; /// Empty matrix class with the interface of a BaseMatrix @@ -273,26 +287,42 @@ class EmptyMatrix : public sofa::linearalgebra::BaseMatrix } SReal element(Index i, Index j) const override { + SOFA_UNUSED(i); + SOFA_UNUSED(j); return {}; } void resize(Index nbRow, Index nbCol) override { + SOFA_UNUSED(nbRow); + SOFA_UNUSED(nbCol); } void clear() override { } void set(Index i, Index j, double v) override { + SOFA_UNUSED(i); + SOFA_UNUSED(j); + SOFA_UNUSED(v); } void add(Index row, Index col, double v) override { + SOFA_UNUSED(row); + SOFA_UNUSED(col); + SOFA_UNUSED(v); //add method is empty to prevent crashes in tests } void add(Index row, Index col, const sofa::type::Mat3x3d& _M) override { + SOFA_UNUSED(row); + SOFA_UNUSED(col); + SOFA_UNUSED(_M); } void add(Index row, Index col, const sofa::type::Mat3x3f& _M) override { + SOFA_UNUSED(row); + SOFA_UNUSED(col); + SOFA_UNUSED(_M); } static const char* Name() { return "EmptyMatrix"; } }; diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.h b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.h index 7bf769b9c3a3..4cc2bfbae6d2 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.h +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.h @@ -82,41 +82,27 @@ class EllipsoidForceField : public core::behavior::ForceField }; - union - { - SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DEPRECATED() Data > contacts; ///< Contacts - Data > d_contacts; ///< Contacts - }; + Data > d_contacts; ///< Vector of contacts + SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DISABLED() DeprecatedAndRemoved contacts; ///< Contacts EllipsoidForceFieldInternalData data; public: - union - { - Data d_center; ///< ellipsoid center - SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DEPRECATED() Data center; ///< ellipsoid center - }; - union - { - Data d_vradius; ///< ellipsoid radius - SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DEPRECATED() Data vradius; ///< ellipsoid radius - }; - union - { - Data d_stiffness; ///< force stiffness (positive to repulse outward, negative inward) - SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DEPRECATED() Data stiffness; ///< force stiffness (positive to repulse outward, negative inward) - }; - union - { - Data d_damping; ///< force damping - SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DEPRECATED() Data damping; ///< force damping - }; - union - { - Data d_color; ///< ellipsoid color. (default=0,0.5,1.0,1.0) - SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DEPRECATED() Data color; ///< ellipsoid color. (default=0,0.5,1.0,1.0) - }; + Data d_center; ///< ellipsoid center + SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DISABLED() DeprecatedAndRemoved center; ///< ellipsoid center + + Data d_vradius; ///< ellipsoid radius + SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DISABLED() DeprecatedAndRemoved vradius; ///< ellipsoid radius + + Data d_stiffness; ///< force stiffness (positive to repulse outward, negative inward) + SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DISABLED() DeprecatedAndRemoved stiffness; ///< force stiffness (positive to repulse outward, negative inward) + + Data d_damping; ///< force damping + SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DISABLED() DeprecatedAndRemoved damping; ///< force damping + + Data d_color; ///< ellipsoid color. (default=0,0.5,1.0,1.0) + SOFA_ELLIPSOIDFORCEFIELD_RENAMEDDATA_DISABLED() DeprecatedAndRemoved color; ///< ellipsoid color. (default=0,0.5,1.0,1.0) protected: EllipsoidForceField(); diff --git a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.inl b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.inl index 4459517d8eb9..49c6a8c2527e 100644 --- a/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.inl +++ b/Sofa/Component/MechanicalLoad/src/sofa/component/mechanicalload/EllipsoidForceField.inl @@ -57,7 +57,7 @@ namespace sofa::component::mechanicalload template EllipsoidForceField::EllipsoidForceField() - : d_contacts(initData(&d_contacts,"contacts", "Contacts")) + : d_contacts(initData(&d_contacts,"contacts", "Vector of contacts")) , d_center(initData(&d_center, "center", "ellipsoid center")) , d_vradius(initData(&d_vradius, "vradius", "ellipsoid radius")) , d_stiffness(initData(&d_stiffness, (Real)500, "stiffness", "force stiffness (positive to repulse outward, negative inward)")) @@ -69,12 +69,6 @@ EllipsoidForceField::EllipsoidForceField() template EllipsoidForceField::~EllipsoidForceField() { - d_contacts.~Data(); - d_center.~Data(); - d_vradius.~Data(); - d_stiffness.~Data(); - d_damping.~Data(); - d_color.~Data(); } template @@ -115,7 +109,7 @@ void EllipsoidForceField::addForce(const sofa::core::MechanicalParams { Coord dp = p1[i] - center; Real norm2 = 0; - for (int j=0; j void TriangularFEMForceFieldOptim::computePrincipalStress() { const VecElement& triangles = m_topology->getTriangles(); - - sofa::helper::ReadAccessor< core::objectmodel::Data< VecTriangleState > > triStates = d_triangleState; sofa::helper::WriteAccessor< core::objectmodel::Data< VecTriangleInfo > > triInfos = d_triangleInfo; Real minStress = 0; diff --git a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixGeneric.h b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixGeneric.h index 4647c6f9a1a5..31fd33baf5c7 100644 --- a/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixGeneric.h +++ b/Sofa/framework/LinearAlgebra/src/sofa/linearalgebra/CompressedRowSparseMatrixGeneric.h @@ -263,7 +263,7 @@ public : /// Returns the range of indices from the column indices corresponding to the id-th row Range getRowRange(Index id) const { - if (id + 1 >= rowBegin.size()) + if (id + 1 >= static_cast(rowBegin.size())) { return Range(s_invalidIndex, s_invalidIndex); } diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp b/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp index 0bf53d191c82..5d54680785bb 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp @@ -71,6 +71,7 @@ DefaultAnimationLoop::DefaultAnimationLoop(simulation::Node* _m_node) : Inherit() , d_parallelODESolving(initData(&d_parallelODESolving, false, "parallelODESolving", "If true, solves all the ODEs in parallel")) { + SOFA_UNUSED(_m_node); this->addUpdateCallback("parallelODESolving", {&d_parallelODESolving}, [this](const core::DataTracker& tracker) -> sofa::core::objectmodel::ComponentState { diff --git a/applications/collections/deprecated/modules/SofaMiscCollision/SofaMiscCollision_test/DefaultCollisionGroupManager_test.cpp b/applications/collections/deprecated/modules/SofaMiscCollision/SofaMiscCollision_test/DefaultCollisionGroupManager_test.cpp index 8c5514b36584..8df65f4ce69a 100644 --- a/applications/collections/deprecated/modules/SofaMiscCollision/SofaMiscCollision_test/DefaultCollisionGroupManager_test.cpp +++ b/applications/collections/deprecated/modules/SofaMiscCollision/SofaMiscCollision_test/DefaultCollisionGroupManager_test.cpp @@ -58,15 +58,15 @@ void DefaultCollisionGroupManager_test::onSetUp() + "/DefaultCollisionGroupManager_singleObject_test.scn"; // Init simulation - sofa::simulation::setSimulation(simulation = new sofa::simulation::graph::DAGSimulation()); - root = sofa::simulation::getSimulation()->load(sceneFilename.c_str()); + simulation = sofa::simulation::getSimulation(); + root = sofa::simulation::node::load(sceneFilename.c_str()); } void DefaultCollisionGroupManager_test::onTearDown() { if (root != nullptr) { - sofa::simulation::getSimulation()->unload(root); + sofa::simulation::node::unload(root); } } @@ -75,7 +75,7 @@ bool DefaultCollisionGroupManager_test::combineSingleObject() EXPECT_TRUE(root != nullptr); EXPECT_TRUE(sofa::simulation::getSimulation() != nullptr); - sofa::simulation::getSimulation()->init(root.get()); + sofa::simulation::node::initRoot(root.get()); // run 200 time steps // objectives: @@ -83,7 +83,7 @@ bool DefaultCollisionGroupManager_test::combineSingleObject() // 2) Collision prevents the cube to fall through the floor for (unsigned int i = 0; i < 200; ++i) { - sofa::simulation::getSimulation()->animate(root.get(), 0.01); + sofa::simulation::node::animate(root.get(), 0.01); } auto* baseObject = root->getTreeNode("Cube1")->getObject("mechanicalObject"); diff --git a/applications/collections/deprecated/modules/SofaValidation/SofaValidation_test/Monitor_test.cpp b/applications/collections/deprecated/modules/SofaValidation/SofaValidation_test/Monitor_test.cpp index 4f71d377d385..5c6024decd5e 100644 --- a/applications/collections/deprecated/modules/SofaValidation/SofaValidation_test/Monitor_test.cpp +++ b/applications/collections/deprecated/modules/SofaValidation/SofaValidation_test/Monitor_test.cpp @@ -147,7 +147,7 @@ struct Monitor_test : public BaseSimulationTest // make a few steps before checkinf if values are correctly updated in // Monitor for (int i = 0; i < 10; ++i) - simulation::getSimulation()->animate(root.get(), 1.0); + simulation::node::animate(root.get(), 1.0); monitor->testModif(mo.get()); diff --git a/applications/plugins/CollisionOBBCapsule/examples/benchmark_cubes.scn b/applications/plugins/CollisionOBBCapsule/examples/benchmark_cubes.scn index e3e29fe85d14..bf34abd651d3 100644 --- a/applications/plugins/CollisionOBBCapsule/examples/benchmark_cubes.scn +++ b/applications/plugins/CollisionOBBCapsule/examples/benchmark_cubes.scn @@ -43,7 +43,7 @@ - + @@ -51,7 +51,7 @@ - + @@ -59,7 +59,7 @@ - + @@ -67,7 +67,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -83,7 +83,7 @@ - + @@ -91,7 +91,7 @@ - + @@ -99,7 +99,7 @@ - + @@ -107,7 +107,7 @@ - + @@ -115,7 +115,7 @@ - + @@ -123,7 +123,7 @@ - + @@ -131,7 +131,7 @@ - + @@ -139,7 +139,7 @@ - + @@ -147,7 +147,7 @@ - + @@ -155,7 +155,7 @@ - + @@ -163,7 +163,7 @@ - + @@ -171,7 +171,7 @@ - + @@ -179,7 +179,7 @@ - + @@ -187,7 +187,7 @@ - + @@ -195,7 +195,7 @@ - + @@ -203,7 +203,7 @@ - + @@ -211,7 +211,7 @@ - + @@ -219,7 +219,7 @@ - + @@ -227,7 +227,7 @@ - + @@ -235,7 +235,7 @@ - + @@ -243,7 +243,7 @@ - + @@ -251,7 +251,7 @@ - + @@ -259,7 +259,7 @@ - + @@ -267,7 +267,7 @@ - + @@ -275,7 +275,7 @@ - + @@ -283,7 +283,7 @@ - + @@ -291,7 +291,7 @@ - + @@ -299,7 +299,7 @@ - + @@ -307,7 +307,7 @@ - + @@ -315,7 +315,7 @@ - + @@ -323,7 +323,7 @@ - + @@ -331,7 +331,7 @@ - + @@ -339,7 +339,7 @@ - + @@ -347,7 +347,7 @@ - + @@ -355,7 +355,7 @@ - + @@ -363,7 +363,7 @@ - + @@ -371,7 +371,7 @@ - + @@ -379,7 +379,7 @@ - + @@ -387,7 +387,7 @@ - + @@ -395,7 +395,7 @@ - + @@ -403,7 +403,7 @@ - + @@ -411,7 +411,7 @@ - + @@ -419,7 +419,7 @@ - + @@ -427,7 +427,7 @@ - + @@ -435,7 +435,7 @@ - + @@ -443,7 +443,7 @@ - + @@ -451,7 +451,7 @@ - + @@ -459,7 +459,7 @@ - + @@ -467,7 +467,7 @@ - + @@ -475,7 +475,7 @@ - + @@ -483,7 +483,7 @@ - + @@ -491,7 +491,7 @@ - + @@ -499,7 +499,7 @@ - + @@ -507,7 +507,7 @@ - + @@ -515,7 +515,7 @@ - + @@ -523,7 +523,7 @@ - + @@ -531,7 +531,7 @@ - + @@ -539,7 +539,7 @@ - + @@ -547,7 +547,7 @@ - + @@ -555,7 +555,7 @@ - + @@ -563,7 +563,7 @@ - + @@ -571,7 +571,7 @@ - + @@ -579,7 +579,7 @@ - + @@ -587,7 +587,7 @@ - + @@ -595,7 +595,7 @@ - + @@ -603,7 +603,7 @@ - + @@ -611,7 +611,7 @@ - + diff --git a/applications/plugins/MultiThreading/src/MultiThreading/TaskSchedulerUser.cpp b/applications/plugins/MultiThreading/src/MultiThreading/TaskSchedulerUser.cpp index c005b5ee9459..a60da64108f6 100644 --- a/applications/plugins/MultiThreading/src/MultiThreading/TaskSchedulerUser.cpp +++ b/applications/plugins/MultiThreading/src/MultiThreading/TaskSchedulerUser.cpp @@ -65,7 +65,7 @@ void TaskSchedulerUser::reinitTaskScheduler() if (m_taskScheduler) { const auto nbThreads = d_nbThreads.getValue(); - if ( nbThreads != m_taskScheduler->getThreadCount() ) + if ( nbThreads != static_cast(m_taskScheduler->getThreadCount()) ) { m_taskScheduler->init(nbThreads); sofa::simulation::initThreadLocalData(); diff --git a/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h b/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h index 2f12e06811d6..c246aae0a7ce 100644 --- a/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h +++ b/applications/plugins/MultiThreading/src/MultiThreading/component/linearsolver/iterative/ParallelCompressedRowSparseMatrixMechanical.h @@ -125,7 +125,7 @@ class ParallelCompressedRowSparseMatrixMechanical : public sofa::linearalgebra:: // transfer a chunk of large vector to a local block-sized vector sofa::type::Vec v; //Index jN = colsIndex[xj] * NC; // scalar column index - for (Index bj = 0; bj < NC; ++bj) + for (sofa::Index bj = 0; bj < NC; ++bj) { v[bj] = vget(vec, m_crs.colsIndex[xj], NC, bj); } @@ -133,9 +133,9 @@ class ParallelCompressedRowSparseMatrixMechanical : public sofa::linearalgebra:: // multiply the block with the local vector const typename Base::Block& b = m_crs.colsValue[xj]; // non-null block has block-indices (rowIndex[xi],colsIndex[xj]) and value colsValue[xj] - for (Index bi = 0; bi < NL; ++bi) + for (sofa::Index bi = 0; bi < NL; ++bi) { - for (Index bj = 0; bj < NC; ++bj) + for (sofa::Index bj = 0; bj < NC; ++bj) { r[bi] += Base::traits::v(b, bi, bj) * v[bj]; } @@ -144,7 +144,7 @@ class ParallelCompressedRowSparseMatrixMechanical : public sofa::linearalgebra:: // transfer the local result to the large result vector //Index iN = rowIndex[xi] * NL; // scalar row index - for (Index bi = 0; bi < NL; ++bi) + for (sofa::Index bi = 0; bi < NL; ++bi) { vset(res, m_crs.rowIndex[xi], NL, bi, r[bi]); } diff --git a/applications/plugins/SensableEmulation/examples/SimpleBox-Method2.scn b/applications/plugins/SensableEmulation/examples/SimpleBox-Method2.scn index f1ad8c485b3d..becbb2480b01 100644 --- a/applications/plugins/SensableEmulation/examples/SimpleBox-Method2.scn +++ b/applications/plugins/SensableEmulation/examples/SimpleBox-Method2.scn @@ -53,7 +53,7 @@ - + diff --git a/applications/plugins/image/image_test/ImageEngine_test.cpp b/applications/plugins/image/image_test/ImageEngine_test.cpp index 9549af5a122e..50ad94855fae 100644 --- a/applications/plugins/image/image_test/ImageEngine_test.cpp +++ b/applications/plugins/image/image_test/ImageEngine_test.cpp @@ -54,7 +54,7 @@ struct ImageEngine_test : public sofa::testing::BaseTest void TearDown() { if (root!=NULL) - sofa::simulation::getSimulation()->unload(root); + sofa::simulation::node::unload(root); } // Test link @@ -130,7 +130,7 @@ struct ImageEngine_test : public sofa::testing::BaseTest TestImageEngine::SPtr imageEngine; // Create a scene - sofa::simulation::setSimulation(simulation = new sofa::simulation::graph::DAGSimulation()); + simulation = sofa::simulation::getSimulation(); // Root node root = simulation->createNewGraph("root"); @@ -156,12 +156,12 @@ struct ImageEngine_test : public sofa::testing::BaseTest sofa::modeling::setDataLink(&imageEngine->outputImage,&imageEngine2->inputImage); // Init simulation - sofa::simulation::getSimulation()->init(root.get()); + sofa::simulation::node::initRoot(root.get()); // do several steps of animation for(int l=0;l<2;++l) { - sofa::simulation::getSimulation()->animate(root.get(),0.5); + sofa::simulation::node::animate(root.get(),0.5); } // Check if pointers of images that should be shared are equal @@ -190,7 +190,7 @@ struct ImageEngine_test : public sofa::testing::BaseTest ImageViewer::SPtr imageViewer; // Create a scene - sofa::simulation::setSimulation(simulation = new sofa::simulation::graph::DAGSimulation()); + simulation = sofa::simulation::getSimulation(); // Root node root = simulation->createNewGraph("root"); @@ -221,12 +221,12 @@ struct ImageEngine_test : public sofa::testing::BaseTest //sofa::modeling::setDataLink(&imageContainer->image,&imageViewer->image); // Init simulation - sofa::simulation::getSimulation()->init(root.get()); + sofa::simulation::node::initRoot(root.get()); // do several steps of animation for(int l=0;l<2;++l) { - sofa::simulation::getSimulation()->animate(root.get(),0.5); + sofa::simulation::node::animate(root.get(),0.5); } diff --git a/applications/projects/SofaPhysicsAPI/src/SofaPhysicsAPI/SofaPhysicsBindings.cpp b/applications/projects/SofaPhysicsAPI/src/SofaPhysicsAPI/SofaPhysicsBindings.cpp index 0e2ae2a35733..c3e830658736 100644 --- a/applications/projects/SofaPhysicsAPI/src/SofaPhysicsAPI/SofaPhysicsBindings.cpp +++ b/applications/projects/SofaPhysicsAPI/src/SofaPhysicsAPI/SofaPhysicsBindings.cpp @@ -354,7 +354,7 @@ int sofaVisualModel_getNbEdges(void* api_ptr, const char* name) } -int sofaVisualModel_getEdges(void* api_ptr, const char* name, int* buffer) +int sofaVisualModel_getEdges(void* /*api_ptr*/, const char* /*name*/, int* /*buffer*/) { //TODO diff --git a/applications/tutorials/chainHybrid/chainHybrid.cpp b/applications/tutorials/chainHybrid/chainHybrid.cpp index fd5245e43abd..543518970995 100644 --- a/applications/tutorials/chainHybrid/chainHybrid.cpp +++ b/applications/tutorials/chainHybrid/chainHybrid.cpp @@ -244,7 +244,6 @@ int main(int argc, char** argv) sofa::gui::common::GUIManager::Init(argv[0]); auto simulation = sofa::simpleapi::createSimulation(); - sofa::simulation::setSimulation( simulation.get() ); // The graph root node Node::SPtr root = sofa::modeling::createRootWithCollisionPipeline(); @@ -255,7 +254,7 @@ int main(int argc, char** argv) root->setAnimate(false); - sofa::simulation::getSimulation()->init(root.get()); + sofa::simulation::node::initRoot(root.get()); //======================================= diff --git a/applications/tutorials/compositeObject/compositeObject.cpp b/applications/tutorials/compositeObject/compositeObject.cpp index ede322d8a9a9..cd9a2cefe616 100644 --- a/applications/tutorials/compositeObject/compositeObject.cpp +++ b/applications/tutorials/compositeObject/compositeObject.cpp @@ -256,13 +256,11 @@ int main(int argc, char** argv) if (int err=sofa::gui::common::GUIManager::createGUI(NULL)) return err; sofa::gui::common::GUIManager::SetDimension(800,600); - sofa::simulation::setSimulation(new sofa::simulation::graph::DAGSimulation()); - //================================================= sofa::simulation::Node::SPtr groot = createGridScene(Vec3(0,0,0), Vec3(5,1,1), 6,2,2, 1.0 ); //================================================= - sofa::simulation::getSimulation()->init(groot.get()); + sofa::simulation::node::initRoot(groot.get()); sofa::gui::common::GUIManager::SetScene(groot); groot->setAnimate(true); @@ -271,7 +269,7 @@ int main(int argc, char** argv) if (int err = sofa::gui::common::GUIManager::MainLoop(groot)) return err; - sofa::simulation::getSimulation()->unload(groot); + sofa::simulation::node::unload(groot); sofa::gui::common::GUIManager::closeGUI(); sofa::simulation::graph::cleanup(); diff --git a/applications/tutorials/mixedPendulum/mixedPendulum.cpp b/applications/tutorials/mixedPendulum/mixedPendulum.cpp index f7084a5ed356..41e2a186ac0b 100644 --- a/applications/tutorials/mixedPendulum/mixedPendulum.cpp +++ b/applications/tutorials/mixedPendulum/mixedPendulum.cpp @@ -66,7 +66,6 @@ int main(int argc, char** argv) double splength = 1.; //-------------------- The graph root node - sofa::simulation::setSimulation(new sofa::simulation::graph::DAGSimulation()); auto groot = sofa::simulation::getSimulation()->createNewGraph("root"); groot->setGravity({ 0,-10,0 }); @@ -199,7 +198,7 @@ int main(int argc, char** argv) sofa::gui::common::GUIManager::SetDimension(800, 600); //=========================== Init the scene - sofa::simulation::getSimulation()->init(groot.get()); + sofa::simulation::node::initRoot(groot.get()); sofa::gui::common::GUIManager::SetScene(groot); groot->setAnimate(true); @@ -208,9 +207,8 @@ int main(int argc, char** argv) sofa::gui::common::GUIManager::MainLoop(groot); if (groot != NULL) - sofa::simulation::getSimulation()->unload(groot); + sofa::simulation::node::unload(groot); sofa::simulation::graph::cleanup(); return 0; } - diff --git a/applications/tutorials/oneParticle/oneParticle.cpp b/applications/tutorials/oneParticle/oneParticle.cpp index b8f405609b4b..f0697745daa4 100644 --- a/applications/tutorials/oneParticle/oneParticle.cpp +++ b/applications/tutorials/oneParticle/oneParticle.cpp @@ -64,7 +64,6 @@ int main(int argc, char** argv) sofa::gui::common::GUIManager::Init(argv[0]); // The graph root node - sofa::simulation::setSimulation(new sofa::simulation::graph::DAGSimulation()); sofa::simulation::Node::SPtr groot = sofa::simulation::getSimulation()->createNewGraph("root"); groot->setGravity({ 0,-10,0 }); @@ -113,7 +112,7 @@ int main(int argc, char** argv) flags.setShowCollisionModels(true); style->displayFlags.endEdit(); - sofa::simulation::graph::getSimulation()->init(groot.get()); + sofa::simulation::node::initRoot(groot.get()); groot->setAnimate(false); //====================================== From 3ae2d8794bd5ba52f2969f6f30523dde6703fc1a Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Mon, 4 Dec 2023 02:28:56 +0100 Subject: [PATCH 50/60] [FEM.Elastic] Reference instead of a copy in TriangularFEMForceField (#4332) * remove collision pipeline * [FEM.Elastic] Reference instead of a copy in TriangularFEMForceField As it appears in the initialization, it won't affect the performances during the simulation * Missing required plugins --- .../fem/elastic/TriangularFEMForceField.inl | 2 +- .../FEM/TriangularFEMForceField.scn | 34 ++++++++----------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceField.inl b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceField.inl index 1c4d719f71b5..f0a7b3218dac 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceField.inl +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TriangularFEMForceField.inl @@ -215,7 +215,7 @@ void TriangularFEMForceField::initLarge(int i, Index& a, Index& b, In } else { - VecCoord initialPoints = (this->mstate->read(core::ConstVecCoordId::restPosition())->getValue()); + const VecCoord& initialPoints = (this->mstate->read(core::ConstVecCoordId::restPosition())->getValue()); tinfo->rotation = tinfo->initialTransformation; if (a >= (initialPoints).size() || b >= (initialPoints).size() || c >= (initialPoints).size()) { diff --git a/examples/Component/SolidMechanics/FEM/TriangularFEMForceField.scn b/examples/Component/SolidMechanics/FEM/TriangularFEMForceField.scn index 5b28fade3ca6..93562748dea7 100644 --- a/examples/Component/SolidMechanics/FEM/TriangularFEMForceField.scn +++ b/examples/Component/SolidMechanics/FEM/TriangularFEMForceField.scn @@ -1,25 +1,21 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - From 07c4df5ee03bc8a03ef22bf78878c584fdeda012 Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Mon, 4 Dec 2023 05:29:01 +0100 Subject: [PATCH 51/60] [SolidMechanics.Springs] Cleaning of QuadularBendingSprings (#4304) * Massive cleaning * Implement buildStiffnessMatrix * final cleaning --- .../spring/QuadularBendingSprings.h | 47 +- .../spring/QuadularBendingSprings.inl | 436 +++++++----------- .../Spring/QuadularBendingSprings.scn | 69 ++- 3 files changed, 220 insertions(+), 332 deletions(-) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.h index 80485ee7f5c3..f8709ac2f5c3 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.h @@ -75,25 +75,31 @@ class QuadularBendingSprings : public core::behavior::ForceField class EdgeInformation { public: - Mat DfDx; /// the edge stiffness matrix - int m1, m2; /// the two extremities of the first spring: masses m1 and m2 - int m3, m4; /// the two extremities of the second spring: masses m3 and m4 + struct Spring + { + sofa::topology::Edge edge; + Real restLength; + Mat DfDx; /// the edge stiffness matrix + }; - SReal ks; /// spring stiffness (initialized to the default value) - SReal kd; /// damping factor (initialized to the default value) + sofa::type::fixed_array springs; - SReal restlength1; /// rest length of the first spring - SReal restlength2; /// rest length of the second spring + SReal ks {}; /// spring stiffness + SReal kd {}; /// damping factor bool is_activated; bool is_initialized; - EdgeInformation(int m1=0, int m2=0, int m3=0, int m4=0, SReal restlength1=0.0, SReal restlength2=0.0, bool is_activated=false, bool is_initialized=false) - : m1(m1), m2(m2), m3(m3), m4(m4), restlength1(restlength1), restlength2(restlength2), is_activated(is_activated), is_initialized(is_initialized) - { - } + EdgeInformation(int m1 = 0, int m2 = 0, int m3 = 0, int m4 = 0, + SReal restlength1 = 0_sreal, SReal restlength2 = 0_sreal, + const bool is_activated = false, const bool is_initialized = false) + : springs{ + Spring{ {m1, m2}, restlength1}, + Spring{ {m3, m4}, restlength2} + }, is_activated(is_activated), is_initialized(is_initialized) + { } /// Output stream inline friend std::ostream& operator<< ( std::ostream& os, const EdgeInformation& /*ei*/ ) @@ -108,14 +114,13 @@ class QuadularBendingSprings : public core::behavior::ForceField } }; - - public: /// Searches quad topology and creates the bending springs void init() override; void addForce(const core::MechanicalParams* mparams, DataVecDeriv& d_f, const DataVecCoord& d_x, const DataVecDeriv& d_v) override; void addDForce(const core::MechanicalParams* mparams, DataVecDeriv& d_df, const DataVecDeriv& d_dx) override; + void buildStiffnessMatrix(core::behavior::StiffnessMatrix* matrix) override; void buildDampingMatrix(core::behavior::DampingMatrix* /*matrix*/) final; SReal getPotentialEnergy(const core::MechanicalParams* /* mparams */, const DataVecCoord& /* d_x */) const override; @@ -132,10 +137,7 @@ class QuadularBendingSprings : public core::behavior::ForceField f_kd.setValue((SReal)kd); } - // -- VisualModel interface void draw(const core::visual::VisualParams* vparams) override; - void initTextures() { } - void update() { } sofa::core::topology::EdgeData > &getEdgeInfo() {return edgeInfo;} @@ -178,6 +180,19 @@ class QuadularBendingSprings : public core::behavior::ForceField protected: sofa::core::topology::EdgeData > edgeInfo; ///< Internal edge data + struct ForceOutput + { + Deriv force; + Real forceIntensity; + Real inverseLength; + }; + + ForceOutput computeForce(const VecDeriv& v, const EdgeInformation& einfo, const typename EdgeInformation::Spring& spring, Coord direction, Real distance); + Mat computeLocalJacobian(EdgeInformation& einfo, const Coord& direction, const ForceOutput& force); + void computeSpringForce(VecDeriv& f, const VecCoord& x, const VecDeriv& v, + EdgeInformation& einfo, + typename EdgeInformation::Spring& spring); + /// Pointer to the current topology sofa::core::topology::BaseMeshTopology* m_topology; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.inl index 3c352c1b6a80..3f4674fa59bc 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/QuadularBendingSprings.inl @@ -40,14 +40,10 @@ template< class DataTypes> void QuadularBendingSprings::applyEdgeCreation(Index /*edgeIndex*/, EdgeInformation &ei, const core::topology::Edge &, const sofa::type::vector &, const sofa::type::vector &) { - unsigned int u,v; /// set to zero the edge stiffness matrix - for (u=0; u::applyQuadCreation(const sofa::type::vect EdgeInformation &ei = edgeData[te2[j]]; // ff->edgeInfo if(!(ei.is_initialized)) { - unsigned int edgeIndex = te2[j]; ei.is_activated=true; /// set to zero the edge stiffness matrix - for (u=0; um_topology->getQuadsAroundEdge(edgeIndex); @@ -105,14 +97,11 @@ void QuadularBendingSprings::applyQuadCreation(const sofa::type::vect if(shell[0] == quadAdded[i]) { - te1 = this->m_topology->getEdgesInQuad(shell[1]); t1 = this->m_topology->getQuad(shell[1]); - } else // shell[1] == quadAdded[i] { - te1 = this->m_topology->getEdgesInQuad(shell[0]); t1 = this->m_topology->getQuad(shell[0]); } @@ -120,32 +109,27 @@ void QuadularBendingSprings::applyQuadCreation(const sofa::type::vect const int i1 = this->m_topology->getEdgeIndexInQuad(te1, edgeIndex); //edgeIndex //te1[j] const int i2 = this->m_topology->getEdgeIndexInQuad(te2, edgeIndex); // edgeIndex //te2[j] - ei.m1 = t1[i1]; // i1 - ei.m2 = t2[(i2+3)%4]; // i2 + ei.springs[0].edge[0] = t1[i1]; // i1 + ei.springs[0].edge[1] = t2[(i2+3)%4]; // i2 - ei.m3 = t1[(i1+3)%4]; // (i1+3)%4 - ei.m4 = t2[i2]; // (i2+3)%4 + ei.springs[1].edge[0] = t1[(i1+3)%4]; // (i1+3)%4 + ei.springs[1].edge[1] = t2[i2]; // (i2+3)%4 //QuadularBendingSprings *fftest= (QuadularBendingSprings *)param; ei.ks=m_ks; //(fftest->ks).getValue(); ei.kd=m_kd; //(fftest->kd).getValue(); - Coord u1 = (restPosition)[ei.m1] - (restPosition)[ei.m2]; - Real d1 = u1.norm(); - ei.restlength1=(SReal) d1; - - Coord u2 = (restPosition)[ei.m3] - (restPosition)[ei.m4]; - Real d2 = u2.norm(); - ei.restlength2=(SReal) d2; + for (auto& s : ei.springs) + { + const Coord diff = restPosition[s.edge[0]] - restPosition[s.edge[1]]; + s.restLength = diff.norm(); + } ei.is_activated=true; - } else { - ei.is_activated=false; - } ei.is_initialized = true; @@ -225,23 +209,21 @@ void QuadularBendingSprings::applyQuadDestruction(const sofa::type::v const int i1 = this->m_topology->getEdgeIndexInQuad(te1, edgeIndex); const int i2 = this->m_topology->getEdgeIndexInQuad(te2, edgeIndex); - ei.m1 = t1[i1]; - ei.m2 = t2[(i2+3)%4]; + ei.springs[0].edge[0] = t1[i1]; + ei.springs[0].edge[1] = t2[(i2+3)%4]; - ei.m3 = t1[(i1+3)%4]; - ei.m4 = t2[i2]; + ei.springs[1].edge[0] = t1[(i1+3)%4]; + ei.springs[1].edge[1] = t2[i2]; //QuadularBendingSprings *fftest= (QuadularBendingSprings *)param; ei.ks=m_ks; //(fftest->ks).getValue(); ei.kd=m_kd; //(fftest->kd).getValue(); - Coord u1 = (restPosition)[ei.m1] - (restPosition)[ei.m2]; - Real d1 = u1.norm(); - ei.restlength1=(SReal) d1; - - Coord u2 = (restPosition)[ei.m3] - (restPosition)[ei.m4]; - Real d2 = u2.norm(); - ei.restlength2=(SReal) d2; + for (auto& s : ei.springs) + { + const Coord u = restPosition[s.edge[0]] - restPosition[s.edge[1]]; + s.restLength = u.norm(); + } ei.is_activated=true; @@ -270,10 +252,7 @@ void QuadularBendingSprings::applyQuadDestruction(const sofa::type::v template< class DataTypes> void QuadularBendingSprings::applyPointDestruction(const sofa::type::vector &tab) { - const bool debug_mode = false; - unsigned int last = this->m_topology->getNbPoints() -1; - unsigned int i,j; helper::WriteOnlyAccessor< Data< type::vector > > edgeInf = edgeInfo; @@ -284,7 +263,7 @@ void QuadularBendingSprings::applyPointDestruction(const sofa::type:: lastIndexVec.push_back(last - i_init); } - for ( i = 0; i < tab.size(); ++i) + for ( unsigned int i = 0; i < tab.size(); ++i) { unsigned int i_next = i; bool is_reached = false; @@ -303,82 +282,30 @@ void QuadularBendingSprings::applyPointDestruction(const sofa::type:: } const auto &shell= this->m_topology->getQuadsAroundVertex(lastIndexVec[i]); - for (j=0; jm_topology->getQuad(shell[j]); const unsigned int vertexIndex = this->m_topology->getVertexIndexInQuad(tj, lastIndexVec[i]); - EdgesInQuad tej = this->m_topology->getEdgesInQuad(shell[j]); + const EdgesInQuad& tej = this->m_topology->getEdgesInQuad(shell[j]); for (unsigned int j_edge=vertexIndex; j_edge%4 !=(vertexIndex+2)%4; ++j_edge) { - unsigned int ind_j = tej[j_edge%4]; - if (edgeInf[ind_j].m1 == (int) last) + for (auto& s : edgeInf[ind_j].springs) { - edgeInf[ind_j].m1=(int) tab[i]; - } - else - { - if (edgeInf[ind_j].m2 == (int) last) - { - edgeInf[ind_j].m2=(int) tab[i]; - } - } - - if (edgeInf[ind_j].m3 == (int) last) - { - edgeInf[ind_j].m3=(int) tab[i]; - } - else - { - if (edgeInf[ind_j].m4 == (int) last) + for (auto& e : s.edge) { - edgeInf[ind_j].m4=(int) tab[i]; - } - } - - } - } - - if(debug_mode) - { - for (unsigned int j_loc=0; j_loc::applyPointDestruction(const sofa::type:: template< class DataTypes> void QuadularBendingSprings::applyPointRenumbering(const sofa::type::vector &tab) { - helper::WriteOnlyAccessor< Data< type::vector > > edgeInf = edgeInfo; - for (unsigned int i = 0; i < this->m_topology->getNbEdges(); ++i) + for (auto& edgeInf : sofa::helper::getWriteOnlyAccessor(edgeInfo)) { - if(edgeInf[i].is_activated) + if (edgeInf.is_activated) { - edgeInf[i].m1 = tab[edgeInf[i].m1]; - edgeInf[i].m2 = tab[edgeInf[i].m2]; - edgeInf[i].m3 = tab[edgeInf[i].m3]; - edgeInf[i].m4 = tab[edgeInf[i].m4]; + for (auto& s : edgeInf.springs) + { + for (auto& e : s.edge) + { + e = tab[e]; + } + } } } } @@ -514,172 +443,148 @@ SReal QuadularBendingSprings::getPotentialEnergy(const core::Mechanic return 0; } +template +auto QuadularBendingSprings::computeForce( + const VecDeriv& v, + const EdgeInformation& einfo, const typename EdgeInformation::Spring& spring, + Coord direction, + Real distance) -> ForceOutput +{ + ForceOutput force; + + force.inverseLength = 1 / distance; + direction *= force.inverseLength; + const Real elongation = distance - spring.restLength; + m_potentialEnergy += elongation * elongation * einfo.ks / 2; + + const Deriv relativeVelocity = v[spring.edge[1]] - v[spring.edge[0]]; + const Real elongationVelocity = sofa::type::dot(direction, relativeVelocity); + force.forceIntensity = einfo.ks * elongation + einfo.kd * elongationVelocity; + force.force = direction * force.forceIntensity; + + return force; +} + +template +auto QuadularBendingSprings::computeLocalJacobian(EdgeInformation& einfo, const Coord& direction, const ForceOutput& force) +-> Mat +{ + const Real tgt = force.forceIntensity * force.inverseLength; + Mat jacobian = (einfo.ks - tgt) * sofa::type::dyad(direction, direction); + for (int j = 0; j < N; ++j) + { + jacobian[j][j] += tgt; + } + return jacobian; +} + +template +void QuadularBendingSprings::computeSpringForce(VecDeriv& f, const VecCoord& x, + const VecDeriv& v, EdgeInformation& einfo, typename EdgeInformation::Spring& spring) +{ + const auto e0 = spring.edge[0]; + const auto e1 = spring.edge[1]; + + const Coord difference = x[e1] - x[e0]; + const Real distance = difference.norm(); + + if (distance > 1.0e-4) + { + const ForceOutput force = computeForce(v, einfo, spring, difference, distance); + + f[e0] += force.force; + f[e1] -= force.force; + + updateMatrix = true; + + spring.DfDx += computeLocalJacobian(einfo, difference / distance, force); + } +} + template void QuadularBendingSprings::addForce(const core::MechanicalParams* /* mparams */, DataVecDeriv& d_f, const DataVecCoord& d_x, const DataVecDeriv& d_v) { - VecDeriv& f = *d_f.beginEdit(); + auto f = sofa::helper::getWriteAccessor(d_f); + const VecCoord& x = d_x.getValue(); const VecDeriv& v = d_v.getValue(); - const size_t nbEdges=m_topology->getNbEdges(); - - EdgeInformation *einfo; - - type::vector& edgeInf = *(edgeInfo.beginEdit()); + auto edgeInf = sofa::helper::getWriteAccessor(edgeInfo); - //const type::vector& m_springs= this->springs.getValue(); - //this->dfdx.resize(nbEdges); //m_springs.size() f.resize(x.size()); m_potentialEnergy = 0; - for(unsigned int i=0; iis_activated) + if (einfo.is_activated) { - //this->addSpringForce(m_potentialEnergy,f,x,v, i, einfo->spring); - - int a1 = einfo->m1; - int b1 = einfo->m2; - int a2 = einfo->m3; - int b2 = einfo->m4; - Coord u1 = x[b1]-x[a1]; - Real d1 = u1.norm(); - Coord u2 = x[b2]-x[a2]; - Real d2 = u2.norm(); - if( d1>1.0e-4 ) - { - Real inverseLength = 1.0f/d1; - u1 *= inverseLength; - Real elongation = (Real)(d1 - einfo->restlength1); - m_potentialEnergy += elongation * elongation * einfo->ks / 2; - - Deriv relativeVelocity = v[b1]-v[a1]; - Real elongationVelocity = dot(u1,relativeVelocity); - Real forceIntensity = (Real)(einfo->ks*elongation+einfo->kd*elongationVelocity); - Deriv force = u1*forceIntensity; - f[a1]+=force; - f[b1]-=force; - - updateMatrix=true; - - Mat& m = einfo->DfDx; //Mat& m = this->dfdx[i]; - Real tgt = forceIntensity * inverseLength; - for( int j=0; jks-tgt) * u1[j] * u1[k]; - } - m[j][j] += tgt; - } - } - else // null length, no force and no stiffness - { - Mat& m = einfo->DfDx; //Mat& m = this->dfdx[i]; - for( int j=0; j1.0e-4 ) - { - Real inverseLength = 1.0f/d2; - u2 *= inverseLength; - Real elongation = (Real)(d2 - einfo->restlength2); - m_potentialEnergy += elongation * elongation * einfo->ks / 2; - - Deriv relativeVelocity = v[b2]-v[a2]; - Real elongationVelocity = dot(u2,relativeVelocity); - Real forceIntensity = (Real)(einfo->ks*elongation+einfo->kd*elongationVelocity); - Deriv force = u2*forceIntensity; - f[a2]+=force; - f[b2]-=force; - - updateMatrix=true; - - Mat& m = einfo->DfDx; //Mat& m = this->dfdx[i]; - Real tgt = forceIntensity * inverseLength; - for( int j=0; jks-tgt) * u2[j] * u2[k]; - } - m[j][j] += tgt; - } - } - else // null length, no force and no stiffness + for (auto& s : einfo.springs) { - Mat& m = einfo->DfDx; //Mat& m = this->dfdx[i]; - for( int j=0; jaddSpringForce(m_potentialEnergy,f,x,v, i, springs[i]); - //} } template void QuadularBendingSprings::addDForce(const core::MechanicalParams* mparams, DataVecDeriv& d_df, const DataVecDeriv& d_dx) { - VecDeriv& df = *d_df.beginEdit(); + auto df = sofa::helper::getWriteAccessor(d_df); const VecDeriv& dx = d_dx.getValue(); Real kFactor = (Real)sofa::core::mechanicalparams::kFactorIncludingRayleighDamping(mparams, this->rayleighStiffness.getValue()); - const size_t nbEdges=m_topology->getNbEdges(); - - const EdgeInformation *einfo; - const type::vector& edgeInf = edgeInfo.getValue(); df.resize(dx.size()); - //const type::vector& springs = this->springs.getValue(); - for(unsigned int i=0; iis_activated) + if (einfo.is_activated) { - //this->addSpringDForce(df,dx, i, einfo->spring); - - const int a1 = einfo->m1; - const int b1 = einfo->m2; - const Coord d1 = dx[b1]-dx[a1]; - const int a2 = einfo->m3; - const int b2 = einfo->m4; - const Coord d2 = dx[b2]-dx[a2]; - const Deriv dforce1 = (einfo->DfDx*d1) * kFactor; - const Deriv dforce2 = (einfo->DfDx*d2) * kFactor; - df[a1]+=dforce1; - df[b1]-=dforce1; - df[a2]+=dforce2; - df[b2]-=dforce2; - - updateMatrix=false; + for (const auto& s : einfo.springs) + { + const auto e0 = s.edge[0]; + const auto e1 = s.edge[1]; + const Coord ddx = dx[e1] - dx[e0]; + const Deriv dforce = s.DfDx * (ddx * kFactor); + + df[e0] += dforce; + df[e1] -= dforce; + } + + updateMatrix = false; } } - d_df.endEdit(); +} + +template +void QuadularBendingSprings::buildStiffnessMatrix( + core::behavior::StiffnessMatrix* matrix) +{ + auto dfdx = matrix->getForceDerivativeIn(this->mstate) + .withRespectToPositionsIn(this->mstate); + + const type::vector& edgeInf = edgeInfo.getValue(); + for (const auto& einfo : edgeInf) + { + if (einfo.is_activated) // edge not in middle of 2 triangles + { + for (const auto& s : einfo.springs) + { + const sofa::Index a = Deriv::total_size * s.edge[0]; + const sofa::Index b = Deriv::total_size * s.edge[1]; + + const auto& dfdxLocal = s.DfDx; + + dfdx(a, a) += -dfdxLocal; + dfdx(a, b) += dfdxLocal; + dfdx(b, a) += dfdxLocal; + dfdx(b, b) += -dfdxLocal; + } + } + } } template @@ -715,44 +620,21 @@ void QuadularBendingSprings::draw(const core::visual::VisualParams* v { if(edgeInf[i].is_activated) { - const bool external=true; - Real d1 = (x[edgeInf[i].m2]-x[edgeInf[i].m1]).norm(); - if (external) + for (const auto& s : edgeInf[i].springs) { - if (d1drawTool()->drawLines(vertices, 1, colors); @@ -768,8 +650,6 @@ void QuadularBendingSprings::draw(const core::visual::VisualParams* v vertices.push_back(x[m_topology->getQuad(i)[j]]); } vparams->drawTool()->drawQuads(vertices, sofa::type::RGBAColor::red()); - - } diff --git a/examples/Component/SolidMechanics/Spring/QuadularBendingSprings.scn b/examples/Component/SolidMechanics/Spring/QuadularBendingSprings.scn index 0d76942ae892..e13e58e6e3d9 100644 --- a/examples/Component/SolidMechanics/Spring/QuadularBendingSprings.scn +++ b/examples/Component/SolidMechanics/Spring/QuadularBendingSprings.scn @@ -1,49 +1,42 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - + - - - - - - - - - - - - + + + + + + + + - + + - + + + + From 9528dbeb8d6e6b0e09fc5121760945bff1a38a3d Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Mon, 4 Dec 2023 17:46:48 +0900 Subject: [PATCH 52/60] [Type] RGBAColor: remove inheritance from type::fixed_array and use std::array to store its components (#4263) * rgbacolor: remove inheritance from fixed_array and use std::array composition * fix datatype info for rgbacolor * add deprecation macro and polish * fix sofacuda * update tests * use sofa size * Apply suggestions from code review (use static field and explicit keyword) Co-authored-by: Alex Bilger * fix and fwd fixed_array in rgbacolor header * Update Sofa/framework/Type/src/sofa/type/config.h.in (change date) Co-authored-by: Hugo * use functions from fixed_array_algo --------- Co-authored-by: Alex Bilger Co-authored-by: Hugo Co-authored-by: Paul Baksic <30337881+bakpaul@users.noreply.github.com> --- Sofa/GL/src/sofa/gl/Axis.cpp | 49 ++++- Sofa/GL/src/sofa/gl/Axis.h | 30 ++- Sofa/GL/src/sofa/gl/DrawToolGL.cpp | 36 ++-- .../Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp | 21 +- .../GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h | 2 + .../src/sofa/gui/qt/viewer/qgl/QtGLViewer.cpp | 2 +- .../Qt/src/sofa/gui/qt/viewer/qt/QtViewer.cpp | 2 +- .../defaulttype/typeinfo/TypeInfo_RGBAColor.h | 2 +- .../Type/src/sofa/type/RGBAColor.cpp | 35 +++- Sofa/framework/Type/src/sofa/type/RGBAColor.h | 183 ++++++++++++++---- Sofa/framework/Type/src/sofa/type/config.h.in | 9 + .../src/sofa/type/fixed_array_algorithms.h | 4 +- Sofa/framework/Type/test/Color_test.cpp | 6 +- .../component/mass/CudaUniformMass.inl | 4 +- 14 files changed, 288 insertions(+), 97 deletions(-) diff --git a/Sofa/GL/src/sofa/gl/Axis.cpp b/Sofa/GL/src/sofa/gl/Axis.cpp index f7da3a42e4aa..751d7d4cd344 100644 --- a/Sofa/GL/src/sofa/gl/Axis.cpp +++ b/Sofa/GL/src/sofa/gl/Axis.cpp @@ -130,7 +130,7 @@ void Axis::initDraw() glEndList(); } -void Axis::draw( const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ ) +void Axis::draw( const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ ) { initDraw(); @@ -263,42 +263,42 @@ Axis::AxisSPtr Axis::get(const type::Vec3& len) return a; } -void Axis::draw(const type::Vec3& center, const Quaternion& orient, const type::Vec3& len, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ ) +void Axis::draw(const type::Vec3& center, const Quaternion& orient, const type::Vec3& len, const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ ) { const auto a = get(len); a->update(center, orient); a->draw( colorX, colorY, colorZ ); } -void Axis::draw(const type::Vec3& center, const double orient[4][4], const type::Vec3& len, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +void Axis::draw(const type::Vec3& center, const double orient[4][4], const type::Vec3& len, const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ) { const auto a = get(len); a->update(center, orient); a->draw( colorX, colorY, colorZ ); } -void Axis::draw(const double *mat, const type::Vec3& len, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +void Axis::draw(const double *mat, const type::Vec3& len, const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ) { const auto a = get(len); a->update(mat); a->draw( colorX, colorY, colorZ ); } -void Axis::draw(const type::Vec3& center, const Quaternion& orient, SReal len, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +void Axis::draw(const type::Vec3& center, const Quaternion& orient, SReal len, const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ) { const auto a = get(type::Vec3(len,len,len)); a->update(center, orient); a->draw( colorX, colorY, colorZ ); } -void Axis::draw(const type::Vec3& center, const double orient[4][4], SReal len, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +void Axis::draw(const type::Vec3& center, const double orient[4][4], SReal len, const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ) { const auto a = get(type::Vec3(len,len,len)); a->update(center, orient); a->draw( colorX, colorY, colorZ ); } -void Axis::draw(const double *mat, SReal len, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +void Axis::draw(const double *mat, SReal len, const type::RGBAColor& colorX, const type::RGBAColor& colorY, const type::RGBAColor& colorZ) { const auto a = get(type::Vec3(len,len,len)); a->update(mat); @@ -389,4 +389,39 @@ void Axis::draw(const type::Vec3& p1, const type::Vec3& p2, const double& r1, co } +void Axis::draw(const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + +void Axis::draw(const type::Vec3& center, const Quaternion& orient, const type::Vec3& length, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(center, orient, length, type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + +void Axis::draw(const type::Vec3& center, const double orient[4][4], const type::Vec3& length, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(center, orient, length, type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + +void Axis::draw(const double* mat, const type::Vec3& length, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(mat, length, type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + +void Axis::draw(const type::Vec3& center, const Quaternion& orient, SReal length, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(center, orient, length, type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + +void Axis::draw(const type::Vec3& center, const double orient[4][4], SReal length, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(center, orient, length, type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + +void Axis::draw(const double* mat, SReal length, const type::Vec4f& colorX, const type::Vec4f& colorY, const type::Vec4f& colorZ) +{ + draw(mat, length, type::RGBAColor::fromVec4(colorX), type::RGBAColor::fromVec4(colorY), type::RGBAColor::fromVec4(colorZ)); +} + } // namespace sofa::gl diff --git a/Sofa/GL/src/sofa/gl/Axis.h b/Sofa/GL/src/sofa/gl/Axis.h index 5295c74ee21e..129a16997e25 100644 --- a/Sofa/GL/src/sofa/gl/Axis.h +++ b/Sofa/GL/src/sofa/gl/Axis.h @@ -22,6 +22,7 @@ #pragma once #include #include +#include #include #include @@ -57,14 +58,29 @@ class SOFA_GL_API Axis void update(const type::Vec3& center, const double orient[4][4]); void update(const double *mat); - void draw( const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); + void draw(const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + static void draw(const type::Vec3& center, const Quaternion& orient, const type::Vec3& length, const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + static void draw(const type::Vec3& center, const double orient[4][4], const type::Vec3& length, const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + static void draw(const double* mat, const type::Vec3& length, const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + static void draw(const type::Vec3& center, const Quaternion& orient, SReal length = 1.0_sreal, const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + static void draw(const type::Vec3& center, const double orient[4][4], SReal length = 1.0_sreal, const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + static void draw(const double* mat, SReal length = 1.0_sreal, const type::RGBAColor& colorX = type::RGBAColor::red(), const type::RGBAColor& colorY = type::RGBAColor::green(), const type::RGBAColor& colorZ = type::RGBAColor::red()); + + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + void draw(const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static void draw(const type::Vec3& center, const Quaternion& orient, const type::Vec3& length, const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static void draw(const type::Vec3& center, const double orient[4][4], const type::Vec3& length, const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + void draw(const double* mat, const type::Vec3& length, const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static void draw(const type::Vec3& center, const Quaternion& orient, SReal length = 1.0_sreal, const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static void draw(const type::Vec3& center, const double orient[4][4], SReal length = 1.0_sreal, const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static void draw(const double* mat, SReal length = 1.0_sreal, const type::Vec4f& colorX = type::Vec4f(1, 0, 0, 1), const type::Vec4f& colorY = type::Vec4f(0, 1, 0, 1), const type::Vec4f& colorZ = type::Vec4f(0, 0, 1, 1)); - static void draw(const type::Vec3& center, const Quaternion& orient, const type::Vec3& length, const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); - static void draw(const type::Vec3& center, const double orient[4][4], const type::Vec3& length, const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); - static void draw(const double *mat, const type::Vec3& length, const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); - static void draw(const type::Vec3& center, const Quaternion& orient, SReal length=1.0_sreal, const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); - static void draw(const type::Vec3& center, const double orient[4][4], SReal length=1.0_sreal, const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); - static void draw(const double *mat, SReal length=1.0_sreal, const type::Vec4f& colorX=type::Vec4f(1,0,0,1), const type::Vec4f& colorY=type::Vec4f(0,1,0,1), const type::Vec4f& colorZ=type::Vec4f(0,0,1,1) ); //Draw a nice vector (cylinder + cone) given 2 points and a radius (used to draw the cylinder) static void draw(const type::Vec3& center, const type::Vec3& ext, const double& radius ); diff --git a/Sofa/GL/src/sofa/gl/DrawToolGL.cpp b/Sofa/GL/src/sofa/gl/DrawToolGL.cpp index ae7b2c608ef3..79becb03757c 100644 --- a/Sofa/GL/src/sofa/gl/DrawToolGL.cpp +++ b/Sofa/GL/src/sofa/gl/DrawToolGL.cpp @@ -437,7 +437,7 @@ void DrawToolGL::drawTriangleFan(const std::vector &points, void DrawToolGL::drawFrame(const Vec3& position, const Quaternion &orientation, const Vec<3,float> &size) { setPolygonMode(0,false); - gl::Axis::draw(position, orientation, size); + gl::Axis::draw(position, orientation, size, type::RGBAColor::red(), type::RGBAColor::green(), type::RGBAColor::blue()); } void DrawToolGL::drawFrame(const Vec3& position, const Quaternion &orientation, const Vec<3,float> &size, const type::RGBAColor &color) { @@ -748,11 +748,11 @@ void DrawToolGL::internalDrawTriangle(const Vec3 &p1,const Vec3 &p2,const Vec3 & const type::RGBAColor &c1, const type::RGBAColor &c2, const type::RGBAColor &c3) { glNormalT(normal); - glColor4fv(c1.array()); + glColor4fv(c1.data()); glVertexNv<3>(p1.ptr()); - glColor4fv(c2.array()); + glColor4fv(c2.data()); glVertexNv<3>(p2.ptr()); - glColor4fv(c3.array()); + glColor4fv(c3.data()); glVertexNv<3>(p3.ptr()); } @@ -762,13 +762,13 @@ void DrawToolGL::internalDrawTriangle(const Vec3 &p1,const Vec3 &p2,const Vec3 & const type::RGBAColor &c1, const type::RGBAColor &c2, const type::RGBAColor &c3) { glNormalT(normal1); - glColor4fv(c1.array()); + glColor4fv(c1.data()); glVertexNv<3>(p1.ptr()); glNormalT(normal2); - glColor4fv(c2.array()); + glColor4fv(c2.data()); glVertexNv<3>(p2.ptr()); glNormalT(normal3); - glColor4fv(c3.array()); + glColor4fv(c3.data()); glVertexNv<3>(p3.ptr()); } @@ -777,7 +777,7 @@ void DrawToolGL::internalDrawTriangle( const Vec3 &p1, const Vec3 &p2, const Vec const Vec3 &normal, const type::RGBAColor &c) { glNormalT(normal); - glColor4fv(c.array()); + glColor4fv(c.data()); glVertexNv<3>(p1.ptr()); glVertexNv<3>(p2.ptr()); glVertexNv<3>(p3.ptr()); @@ -845,7 +845,7 @@ void DrawToolGL::internalDrawQuad(const Vec3 &p1,const Vec3 &p2,const Vec3 &p3,c const Vec3 &normal, const type::RGBAColor &c) { glNormalT(normal); - glColor4fv(c.array()); + glColor4fv(c.data()); glVertexNv<3>(p1.ptr()); glVertexNv<3>(p2.ptr()); glVertexNv<3>(p3.ptr()); @@ -857,13 +857,13 @@ void DrawToolGL::internalDrawQuad(const Vec3 &p1,const Vec3 &p2,const Vec3 &p3,c const type::RGBAColor &c1, const type::RGBAColor &c2, const type::RGBAColor &c3, const type::RGBAColor &c4) { glNormalT(normal); - glColor4fv(c1.array()); + glColor4fv(c1.data()); glVertexNv<3>(p1.ptr()); - glColor4fv(c2.array()); + glColor4fv(c2.data()); glVertexNv<3>(p2.ptr()); - glColor4fv(c3.array()); + glColor4fv(c3.data()); glVertexNv<3>(p3.ptr()); - glColor4fv(c4.array()); + glColor4fv(c4.data()); glVertexNv<3>(p4.ptr()); } @@ -872,16 +872,16 @@ void DrawToolGL::internalDrawQuad(const Vec3 &p1,const Vec3 &p2,const Vec3 &p3,c const type::RGBAColor &c1, const type::RGBAColor &c2, const type::RGBAColor &c3, const type::RGBAColor &c4) { glNormalT(normal1); - glColor4fv(c1.array()); + glColor4fv(c1.data()); glVertexNv<3>(p1.ptr()); glNormalT(normal2); - glColor4fv(c2.array()); + glColor4fv(c2.data()); glVertexNv<3>(p2.ptr()); glNormalT(normal3); - glColor4fv(c3.array()); + glColor4fv(c3.data()); glVertexNv<3>(p3.ptr()); glNormalT(normal4); - glColor4fv(c4.array()); + glColor4fv(c4.data()); glVertexNv<3>(p4.ptr()); } @@ -1411,7 +1411,7 @@ void DrawToolGL::disableDepthTest() ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void DrawToolGL::draw3DText(const Vec3 &p, float scale, const type::RGBAColor &color, const char* text) { - glColor4fv(color.array()); + glColor4fv(color.data()); sofa::gl::GlText::draw(text, p, (double)scale); } diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp index 4110cb16b60f..31bbb94cbe8e 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.cpp @@ -64,7 +64,7 @@ QRGBAColorPicker::QRGBAColorPicker(QWidget* parent) : QWidget(parent) Vec4f QRGBAColorPicker::getColor() const { typedef unsigned char uchar; - const uchar max = std::numeric_limits::max(); + constexpr uchar max = std::numeric_limits::max(); Vec4f color; float r = _r->text().toFloat(); float g = _g->text().toFloat(); @@ -94,14 +94,14 @@ void QRGBAColorPicker::updateRGBAColor() redrawColorButton(); } -void QRGBAColorPicker::setColor(const Vec4f& color) +void QRGBAColorPicker::setColor(const type::RGBAColor& color) { typedef unsigned char uchar; - const uchar max = std::numeric_limits::max(); - const uchar r = uchar( max * color[0] ); - const uchar g = uchar( max * color[1] ); - const uchar b = uchar( max * color[2] ); - const uchar a = uchar( max * color[3] ); + constexpr uchar max = std::numeric_limits::max(); + const uchar r = uchar(max * color[0]); + const uchar g = uchar(max * color[1]); + const uchar b = uchar(max * color[2]); + const uchar a = uchar(max * color[3]); QString str; str.setNum(r); _r->setText(str); @@ -111,11 +111,16 @@ void QRGBAColorPicker::setColor(const Vec4f& color) _b->setText(str); str.setNum(a); _a->setText(str); - _rgba = qRgba(r,g,b,a); + _rgba = qRgba(r, g, b, a); redrawColorButton(); } +void QRGBAColorPicker::setColor(const Vec4f& color) +{ + setColor(type::RGBAColor{color[0], color[1] , color[2] ,color[3]}); +} + void QRGBAColorPicker::redrawColorButton() { const int w=_colorButton->width(); diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h index 15887a577172..8c8fd37bd6fb 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/QRGBAColorPicker.h @@ -58,6 +58,8 @@ class QRGBAColorPicker : public QWidget public: QRGBAColorPicker(QWidget* parent); + void setColor(const type::RGBAColor& color); + void setColor( const Vec4f& color ); Vec4f getColor() const; diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qgl/QtGLViewer.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qgl/QtGLViewer.cpp index 315ff47ccb4a..ab80a8c42996 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qgl/QtGLViewer.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qgl/QtGLViewer.cpp @@ -609,7 +609,7 @@ void QtGLViewer::DisplayOBJs() , this->camera()->orientation()[1] , this->camera()->orientation()[2] , this->camera()->orientation()[3]); - gl::Axis::draw(sofa::type::Vec3(30.0_sreal,30.0_sreal,0.0_sreal),sofaQuat.inverse(), 25.0); + gl::Axis::draw(sofa::type::Vec3(30.0_sreal,30.0_sreal,0.0_sreal),sofaQuat.inverse(), 25.0, sofa::type::RGBAColor::red(), sofa::type::RGBAColor::green(), sofa::type::RGBAColor::blue()); glMatrixMode(GL_PROJECTION); glPopMatrix(); diff --git a/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qt/QtViewer.cpp b/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qt/QtViewer.cpp index 716b07049138..29f4d94fad78 100644 --- a/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qt/QtViewer.cpp +++ b/Sofa/GUI/Qt/src/sofa/gui/qt/viewer/qt/QtViewer.cpp @@ -599,7 +599,7 @@ void QtViewer::DisplayOBJs() glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - gl::Axis::draw(sofa::type::Vec3(30.0,30.0,0.0),currentCamera->getOrientation().inverse(), 25.0); + gl::Axis::draw(sofa::type::Vec3(30.0,30.0,0.0),currentCamera->getOrientation().inverse(), 25.0, sofa::type::RGBAColor::red(), sofa::type::RGBAColor::green(), sofa::type::RGBAColor::blue()); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); diff --git a/Sofa/framework/DefaultType/src/sofa/defaulttype/typeinfo/TypeInfo_RGBAColor.h b/Sofa/framework/DefaultType/src/sofa/defaulttype/typeinfo/TypeInfo_RGBAColor.h index 2d456b27fd36..2a3d63739e07 100644 --- a/Sofa/framework/DefaultType/src/sofa/defaulttype/typeinfo/TypeInfo_RGBAColor.h +++ b/Sofa/framework/DefaultType/src/sofa/defaulttype/typeinfo/TypeInfo_RGBAColor.h @@ -29,7 +29,7 @@ namespace sofa::defaulttype { template<> -class DataTypeInfo< sofa::type::RGBAColor > : public FixedArrayTypeInfo> +class DataTypeInfo< sofa::type::RGBAColor > : public FixedArrayTypeInfo { public: static std::string name() { return "RGBAColor"; } diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp b/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp index 47044186fbf5..d5f67d51a624 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp @@ -24,11 +24,14 @@ #include #include +#include #include + using namespace sofa::type::pairwise; namespace // anonymous { + template T rclamp(const T& value, const T& low, const T& high) { @@ -81,6 +84,12 @@ static void extractValidatedHexaString(std::istream& in, std::string& s) in.clear(in.rdstate() & ~std::ios_base::failbit) ; } + +RGBAColor::RGBAColor(const type::fixed_array& c) + : m_components{ c[0], c[1], c[2], c[3] } +{ +} + bool RGBAColor::read(const std::string& str, RGBAColor& color) { std::stringstream s(str); @@ -93,10 +102,10 @@ bool RGBAColor::read(const std::string& str, RGBAColor& color) void RGBAColor::set(const float r, const float g, const float b, const float a) { - this->elems[0] = r; - this->elems[1] = g; - this->elems[2] = b; - this->elems[3] = a; + this->m_components[0] = r; + this->m_components[1] = g; + this->m_components[2] = b; + this->m_components[3] = a; } @@ -117,13 +126,13 @@ RGBAColor RGBAColor::fromFloat(const float r, const float g, const float b, cons } -RGBAColor RGBAColor::fromVec4(const fixed_array& color) +RGBAColor RGBAColor::fromStdArray(const std::array& color) { return RGBAColor(color) ; } -RGBAColor RGBAColor::fromVec4(const fixed_array& color) +RGBAColor RGBAColor::fromStdArray(const std::array& color) { return RGBAColor(float(color[0]), float(color[1]), float(color[2]), float(color[3])); } @@ -159,6 +168,15 @@ RGBAColor RGBAColor::fromHSVA(const float h, const float s, const float v, const return rgba; } +RGBAColor RGBAColor::fromVec4(const type::fixed_array& color) +{ + return RGBAColor(float(color[0]), float(color[1]), float(color[2]), float(color[3])); +} + +RGBAColor RGBAColor::fromVec4(const type::fixed_array& color) +{ + return RGBAColor(float(color[0]), float(color[1]), float(color[2]), float(color[3])); +} /// This function remove the leading space in the stream. static std::istream& trimInitialSpaces(std::istream& in) @@ -263,8 +281,9 @@ SOFA_TYPE_API std::ostream& operator << ( std::ostream& out, const RGBAColor& t /// @brief enlight a color by a given factor. RGBAColor RGBAColor::lighten(const RGBAColor& in, const SReal factor) { - RGBAColor c = in + ( (RGBAColor::white() - clamp(in, 0.0f, 1.0f)) * rclamp(float(factor), 0.0f, 1.0f)); - c.a()=1.0; + RGBAColor c = in + ( (RGBAColor::white() - RGBAColor::clamp(in, 0.0f, 1.0f)) * rclamp(float(factor), 0.0f, 1.0f)); + + c.a() = 1.0; return c ; } diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.h b/Sofa/framework/Type/src/sofa/type/RGBAColor.h index bd3554f6b442..f649f2ef8f61 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.h +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.h @@ -22,33 +22,55 @@ #pragma once #include -#include +#include #include #include #include #include +#include +#include +#include + +#include namespace sofa::type { -using sofa::type::fixed_array ; - - #define RGBACOLOR_EQUALITY_THRESHOLD 1e-6 /** * \brief encode a 4 RGBA component color */ -class SOFA_TYPE_API RGBAColor : public fixed_array +class SOFA_TYPE_API RGBAColor { public: - static RGBAColor fromString(const std::string& str) ; - static RGBAColor fromFloat(float r, float g, float b, float a) ; - static RGBAColor fromVec4(const fixed_array& color) ; - static RGBAColor fromVec4(const fixed_array& color) ; + static constexpr sofa::Size NumberOfComponents = 4; + using ComponentArray = std::array; + + constexpr RGBAColor() + : m_components{ 1.f, 1.f, 1.f, 1.f } {} + + constexpr explicit RGBAColor(const std::array& c) + : m_components(c) {} + + constexpr RGBAColor(float r, float g, float b, float a) + : m_components{ r, g, b, a } {} - static RGBAColor fromHSVA(float h, float s, float v, float a) ; + // compat + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + RGBAColor(const type::fixed_array& c); + + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static RGBAColor fromVec4(const type::fixed_array& color); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static RGBAColor fromVec4(const type::fixed_array& color); + + static RGBAColor fromString(const std::string& str); + static RGBAColor fromFloat(float r, float g, float b, float a); + static RGBAColor fromStdArray(const std::array& color); + static RGBAColor fromStdArray(const std::array& color); + static RGBAColor fromHSVA(float h, float s, float v, float a); static bool read(const std::string& str, RGBAColor& color) ; @@ -67,33 +89,52 @@ class SOFA_TYPE_API RGBAColor : public fixed_array /// @brief enlight a color by a given factor. static RGBAColor lighten(const RGBAColor& in, const SReal factor); - constexpr float& r(){ return this->elems[0] ; } - constexpr float& g(){ return this->elems[1] ; } - constexpr float& b(){ return this->elems[2] ; } - constexpr float& a(){ return this->elems[3] ; } - constexpr const float& r() const { return this->elems[0] ; } - constexpr const float& g() const { return this->elems[1] ; } - constexpr const float& b() const { return this->elems[2] ; } - constexpr const float& a() const { return this->elems[3] ; } - - constexpr void r(const float r){ this->elems[0]=r; } - constexpr void g(const float g){ this->elems[1]=g; } - constexpr void b(const float b){ this->elems[2]=b; } - constexpr void a(const float a){ this->elems[3]=a; } + constexpr float& r(){ return this->m_components[0] ; } + constexpr float& g(){ return this->m_components[1] ; } + constexpr float& b(){ return this->m_components[2] ; } + constexpr float& a(){ return this->m_components[3] ; } + constexpr const float& r() const { return this->m_components[0] ; } + constexpr const float& g() const { return this->m_components[1] ; } + constexpr const float& b() const { return this->m_components[2] ; } + constexpr const float& a() const { return this->m_components[3] ; } + + constexpr void r(const float r){ this->m_components[0]=r; } + constexpr void g(const float g){ this->m_components[1]=g; } + constexpr void b(const float b){ this->m_components[2]=b; } + constexpr void a(const float a){ this->m_components[3]=a; } + + // operator[] + constexpr float& operator[](std::size_t i) + { + assert(i < NumberOfComponents && "index in RGBAColor must be smaller than 4"); + return m_components[i]; + } + constexpr const float& operator[](std::size_t i) const + { + assert(i < NumberOfComponents && "index in RGBAColor must be smaller than 4"); + return m_components[i]; + } void set(float r, float g, float b, float a) ; - bool operator==(const fixed_array& b) const + bool operator==(const RGBAColor& b) const { for (int i=0; i<4; i++) - if ( fabs( this->elems[i] - b[i] ) > RGBACOLOR_EQUALITY_THRESHOLD ) return false; + if ( fabs( this->m_components[i] - b[i] ) > RGBACOLOR_EQUALITY_THRESHOLD ) return false; return true; } - bool operator!=(const fixed_array& b) const + bool operator!=(const RGBAColor& b) const { for (int i=0; i<4; i++) - if ( fabs( this->elems[i] - b[i] ) > RGBACOLOR_EQUALITY_THRESHOLD ) return true; + if ( fabs( this->m_components[i] - b[i] ) > RGBACOLOR_EQUALITY_THRESHOLD ) return true; + return false; + } + + bool operator<(const RGBAColor& b) const + { + for (int i = 0; i < 4; i++) + if (this->m_components[i] < b[i]) return true; return false; } @@ -102,23 +143,83 @@ class SOFA_TYPE_API RGBAColor : public fixed_array friend SOFA_TYPE_API std::ostream& operator<<(std::ostream& i, const RGBAColor& t) ; friend SOFA_TYPE_API std::istream& operator>>(std::istream& i, RGBAColor& t) ; - constexpr RGBAColor() : fixed_array(1.f, 1.f, 1.f, 1.f) {} - constexpr RGBAColor(const fixed_array& c) : fixed_array(c) {} - constexpr RGBAColor(float r, float g, float b, float a) : fixed_array(r, g, b, a) {} + // direct access to data + constexpr const float* data() const noexcept + { + return m_components.data(); + } + + /// direct access to array + constexpr const ComponentArray& array() const noexcept + { + return m_components; + } + /// direct access to array + constexpr ComponentArray& array() noexcept + { + return m_components; + } + + static constexpr RGBAColor clamp(const RGBAColor& color, float min, float max) + { + RGBAColor result{}; + + for(sofa::Size i = 0 ; i < NumberOfComponents; ++i) + { + result[i] = std::clamp(color[i], min, max); + } + return result; + } + + constexpr ComponentArray::iterator begin() noexcept + { + return m_components.begin(); + } + constexpr ComponentArray::const_iterator begin() const noexcept + { + return m_components.begin(); + } + + constexpr ComponentArray::iterator end() noexcept + { + return m_components.end(); + } + constexpr ComponentArray::const_iterator end() const noexcept + { + return m_components.end(); + } + + static constexpr sofa::Size static_size = NumberOfComponents; + static constexpr sofa::Size size() { return static_size; } + using value_type = float; + using size_type = sofa::Size; + +private: + ComponentArray m_components; }; -inline constexpr RGBAColor g_white {1.0f,1.0f,1.0f,1.0f}; -inline constexpr RGBAColor g_black {0.0f,0.0f,0.0f,1.0f}; -inline constexpr RGBAColor g_red {1.0f,0.0f,0.0f,1.0f}; -inline constexpr RGBAColor g_green {0.0f,1.0f,0.0f,1.0f}; -inline constexpr RGBAColor g_blue {0.0f,0.0f,1.0f,1.0f}; -inline constexpr RGBAColor g_cyan {0.0f,1.0f,1.0f,1.0f}; -inline constexpr RGBAColor g_magenta {1.0f,0.0f,1.0f,1.0f}; -inline constexpr RGBAColor g_yellow {1.0f,1.0f,0.0f,1.0f}; -inline constexpr RGBAColor g_gray {0.5f,0.5f,0.5f,1.0f}; -inline constexpr RGBAColor g_darkgray {0.25f,0.25f,0.25f,1.0f}; -inline constexpr RGBAColor g_lightgray {0.75f,0.75f,0.75f,1.0f}; +constexpr RGBAColor operator-(const RGBAColor& l, const RGBAColor& r) +{ + return sofa::type::pairwise::operator-(l, r); +} + +constexpr RGBAColor operator+(const RGBAColor& l, const RGBAColor& r) +{ + return sofa::type::pairwise::operator+(l, r); +} + +constexpr RGBAColor g_white {1.0f,1.0f,1.0f,1.0f}; +constexpr RGBAColor g_black {0.0f,0.0f,0.0f,1.0f}; +constexpr RGBAColor g_red {1.0f,0.0f,0.0f,1.0f}; +constexpr RGBAColor g_green {0.0f,1.0f,0.0f,1.0f}; +constexpr RGBAColor g_blue {0.0f,0.0f,1.0f,1.0f}; +constexpr RGBAColor g_cyan {0.0f,1.0f,1.0f,1.0f}; +constexpr RGBAColor g_magenta {1.0f,0.0f,1.0f,1.0f}; +constexpr RGBAColor g_yellow {1.0f,1.0f,0.0f,1.0f}; +constexpr RGBAColor g_gray {0.5f,0.5f,0.5f,1.0f}; +constexpr RGBAColor g_darkgray {0.25f,0.25f,0.25f,1.0f}; +constexpr RGBAColor g_lightgray {0.75f,0.75f,0.75f,1.0f}; constexpr const RGBAColor& RGBAColor::white() { return g_white; } constexpr const RGBAColor& RGBAColor::black() { return g_black; } diff --git a/Sofa/framework/Type/src/sofa/type/config.h.in b/Sofa/framework/Type/src/sofa/type/config.h.in index 8c4d79837dd2..cb02a404a1cc 100644 --- a/Sofa/framework/Type/src/sofa/type/config.h.in +++ b/Sofa/framework/Type/src/sofa/type/config.h.in @@ -41,3 +41,12 @@ "v22.12", "v23.06", \ "As an alternative, use sofa::type::Mat::Identity().") #endif + +#ifdef SOFA_BUILD_SOFA_TYPE +#define SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() +#else +#define SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() \ + SOFA_ATTRIBUTE_DEPRECATED( \ + "v23.12", "v24.06", \ + "RGBAColor does not inherit anymore from sofa::type::fixed_array. Use respective functions accordingly.") +#endif diff --git a/Sofa/framework/Type/src/sofa/type/fixed_array_algorithms.h b/Sofa/framework/Type/src/sofa/type/fixed_array_algorithms.h index dc7fe119e138..951fb579a047 100644 --- a/Sofa/framework/Type/src/sofa/type/fixed_array_algorithms.h +++ b/Sofa/framework/Type/src/sofa/type/fixed_array_algorithms.h @@ -46,7 +46,7 @@ T clamp(const T& in, const TT& minValue, const TT& maxValue) /// @brief pairwise add of two fixed_array template -T operator+(const T& l, const T& r) +constexpr T operator+(const T& l, const T& r) { T result {}; for(typename T::size_type i=0; i < typename T::size_type(TN); ++i) @@ -58,7 +58,7 @@ T operator+(const T& l, const T& r) /// @brief pairwise subtract of two fixed_array template -T operator-(const T& l, const T& r) +constexpr T operator-(const T& l, const T& r) { T result {}; for(typename T::size_type i=0; i < typename T::size_type(TN); ++i) diff --git a/Sofa/framework/Type/test/Color_test.cpp b/Sofa/framework/Type/test/Color_test.cpp index 3701c64330e7..c4b062879baa 100644 --- a/Sofa/framework/Type/test/Color_test.cpp +++ b/Sofa/framework/Type/test/Color_test.cpp @@ -134,12 +134,16 @@ void Color_Test::checkCreateFromDouble() const Vec4d tt(2,3,4,5) ; EXPECT_EQ( RGBAColor::fromVec4(tt), RGBAColor(2,3,4,5)) ; + + const std::array stdarrtt{ 2, 3, 4, 5 }; + EXPECT_EQ(RGBAColor::fromStdArray(stdarrtt), RGBAColor(2, 3, 4, 5)); } void Color_Test::checkConstructors() { - EXPECT_EQ( RGBAColor(sofa::type::Vec<4,float>(1,2,3,4)), RGBAColor(1,2,3,4) ) ; + EXPECT_EQ(RGBAColor(std::array{1, 2, 3, 4}), RGBAColor(1, 2, 3, 4)); + EXPECT_EQ( RGBAColor(sofa::type::Vec<4, float>(1, 2, 3, 4)), RGBAColor(1, 2, 3, 4)); } diff --git a/applications/plugins/SofaCUDA/src/SofaCUDA/component/mass/CudaUniformMass.inl b/applications/plugins/SofaCUDA/src/SofaCUDA/component/mass/CudaUniformMass.inl index cd496289a2b8..4e9966287940 100644 --- a/applications/plugins/SofaCUDA/src/SofaCUDA/component/mass/CudaUniformMass.inl +++ b/applications/plugins/SofaCUDA/src/SofaCUDA/component/mass/CudaUniformMass.inl @@ -241,7 +241,7 @@ void UniformMass::draw(const core::visual::VisualPa for (unsigned int i=0; i::draw(const core::visual::VisualPa for (unsigned int i=0; i Date: Tue, 5 Dec 2023 18:40:26 +0900 Subject: [PATCH 53/60] [All] ColorMap uses RGBAColor (#4270) * colormap use rgbcolor * add an other version for fromVec4 --- .../fem/elastic/TetrahedronFEMForceField.h | 2 +- .../fem/elastic/TetrahedronFEMForceField.inl | 10 ++-- .../gl/component/rendering3d/DataDisplay.cpp | 24 ++++---- .../Helper/src/sofa/helper/ColorMap.cpp | 59 ++++++++++--------- .../Helper/src/sofa/helper/ColorMap.h | 19 +++--- .../Type/src/sofa/type/RGBAColor.cpp | 11 ++++ Sofa/framework/Type/src/sofa/type/RGBAColor.h | 15 +++++ 7 files changed, 84 insertions(+), 56 deletions(-) diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.h index fd934892fefe..e357c896a400 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.h +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.h @@ -224,7 +224,7 @@ class TetrahedronFEMForceField : public core::behavior::ForceField, p Data _computeVonMisesStress; ///< compute and display von Mises stress: 0: no computations, 1: using corotational strain, 2: using full Green strain Data > _vonMisesPerElement; ///< von Mises Stress per element Data > _vonMisesPerNode; ///< von Mises Stress per node - Data > _vonMisesStressColors; ///< Vector of colors describing the VonMises stress + Data > _vonMisesStressColors; ///< Vector of colors describing the VonMises stress Real m_minVonMisesPerNode; Real m_maxVonMisesPerNode; diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.inl b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.inl index 6feea67d608f..f7be5b0ab61d 100644 --- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.inl +++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/TetrahedronFEMForceField.inl @@ -1900,7 +1900,7 @@ void TetrahedronFEMForceField::drawTrianglesFromRangeOfTetrahedra( else { sofa::helper::ColorMap::evaluator evalColor = this->m_VonMisesColorMap->getEvaluator(minVM, maxVM); - auto col = sofa::type::RGBAColor::fromVec4(evalColor(vM[elementId])); + auto col = evalColor(vM[elementId]); col[3] = 1.0f; color[0] = col; color[1] = col; @@ -2542,7 +2542,7 @@ void TetrahedronFEMForceField::computeVonMisesStress() updateVonMisesStress=false; - helper::WriteAccessor > > vonMisesStressColors(_vonMisesStressColors); + helper::WriteAccessor > > vonMisesStressColors(_vonMisesStressColors); vonMisesStressColors.clear(); type::vector vonMisesStressColorsCoeff; @@ -2565,12 +2565,12 @@ void TetrahedronFEMForceField::computeVonMisesStress() for(it = _indexedElements->begin() ; it != _indexedElements->end() ; ++it, ++i) { helper::ColorMap::evaluator evalColor = m_VonMisesColorMap->getEvaluator(minVM, maxVM); - const type::Vec4f col = evalColor(vME[i]); + const auto col = evalColor(vME[i]); Tetrahedron tetra = (*_indexedElements)[i]; for(unsigned int j=0 ; j<4 ; j++) { - vonMisesStressColors[tetra[j]] += (col); + vonMisesStressColors[tetra[j]] = vonMisesStressColors[tetra[j]]+(col); vonMisesStressColorsCoeff[tetra[j]] ++; } } @@ -2579,7 +2579,7 @@ void TetrahedronFEMForceField::computeVonMisesStress() { if(vonMisesStressColorsCoeff[i] != 0) { - vonMisesStressColors[i] /= vonMisesStressColorsCoeff[i]; + vonMisesStressColors[i] = vonMisesStressColors[i] / vonMisesStressColorsCoeff[i]; } } } diff --git a/Sofa/GL/Component/Rendering3D/src/sofa/gl/component/rendering3d/DataDisplay.cpp b/Sofa/GL/Component/Rendering3D/src/sofa/gl/component/rendering3d/DataDisplay.cpp index fb8a266112e8..698d214bc9c1 100644 --- a/Sofa/GL/Component/Rendering3D/src/sofa/gl/component/rendering3d/DataDisplay.cpp +++ b/Sofa/GL/Component/Rendering3D/src/sofa/gl/component/rendering3d/DataDisplay.cpp @@ -252,7 +252,7 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) { RGBAColor color = std::isnan(triData[i]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(triData[i])); + : eval(triData[i]); color[3] = transparency; const Triangle& t = m_topology->getTriangle(i); vparams->drawTool()->drawTriangle( @@ -272,15 +272,15 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) { RGBAColor color0 = std::isnan(pointTriData[i*3]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointTriData[i*3])); + : eval(pointTriData[i*3]); color0[3] = transparency; RGBAColor color1 = std::isnan(pointTriData[i*3+1]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointTriData[i*3+1])); + : eval(pointTriData[i*3+1]); color1[3] = transparency; RGBAColor color2 = std::isnan(pointTriData[i*3+2]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointTriData[i*3+2])); + : eval(pointTriData[i*3+2]); color2[3] = transparency; const Triangle& t = m_topology->getTriangle(i); @@ -308,7 +308,7 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) { RGBAColor color = std::isnan(quadData[i]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(quadData[i])); + : eval(quadData[i]); color[3] = transparency; const Quad& t = m_topology->getQuad(i); vparams->drawTool()->drawQuad( @@ -326,18 +326,18 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) { RGBAColor color0 = std::isnan(pointQuadData[i*4]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointQuadData[i*4])); + : eval(pointQuadData[i*4]); RGBAColor color1 = std::isnan(pointQuadData[i*4+1]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointQuadData[i*4+1])); + : eval(pointQuadData[i*4+1]); color1[3] = transparency; RGBAColor color2 = std::isnan(pointQuadData[i*4+2]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointQuadData[i*4+2])); + : eval(pointQuadData[i*4+2]); color2[3] = transparency; RGBAColor color3 = std::isnan(pointQuadData[i*4+3]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(pointQuadData[i*4+3])); + : eval(pointQuadData[i*4+3]); color1[3] = transparency; const Quad& q = m_topology->getQuad(i); @@ -370,7 +370,7 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) { RGBAColor color = std::isnan(ptData[i]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(ptData[i])); + : eval(ptData[i]); color[3] = transparency; vparams->drawTool()->drawPoint(x[i], color); } @@ -388,7 +388,7 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) for (int j=0; j<3; j++) { color[j] = std::isnan(ptData[t[j]]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(ptData[t[j]])); + : eval(ptData[t[j]]); color[j][3] = transparency; } glNormal3fv(m_normals[t[0]].ptr()); @@ -416,7 +416,7 @@ void DataDisplay::doDrawVisual(const core::visual::VisualParams* vparams) { color[j] = std::isnan(ptData[q[j]]) ? f_colorNaN.getValue() - : RGBAColor::fromVec4(eval(ptData[q[j]])); + : eval(ptData[q[j]]); color[j][3] = transparency; } diff --git a/Sofa/framework/Helper/src/sofa/helper/ColorMap.cpp b/Sofa/framework/Helper/src/sofa/helper/ColorMap.cpp index e80ce082233e..60cb9448ea3a 100644 --- a/Sofa/framework/Helper/src/sofa/helper/ColorMap.cpp +++ b/Sofa/framework/Helper/src/sofa/helper/ColorMap.cpp @@ -174,136 +174,136 @@ void ColorMap::reinit() const float step = (2.0f/3.0f)/(nColors-1); for (unsigned int i=0; i #include +#include #include #include #include @@ -40,10 +41,7 @@ namespace helper class SOFA_HELPER_API ColorMap { public: - - typedef type::Vec3f Color3; // Color tripplet - typedef type::Vec4f Color; // ... with alpha value - typedef sofa::type::vector VecColor; + typedef sofa::type::vector VecColor; ColorMap(unsigned int paletteSize = 256, const std::string& colorScheme = "HSV"); virtual ~ColorMap(); @@ -59,7 +57,7 @@ class SOFA_HELPER_API ColorMap evaluator(const ColorMap* map, Real vmin, Real vmax) : map(map), vmin(vmin), vmax(vmax), vscale((vmax == vmin) ? (Real)0 : (map->entries.size()-1)/(vmax-vmin)) {} - Color operator()(Real r) const + auto operator()(Real r) const { Real e = (r-vmin)*vscale; if (e<0) return map->entries.front(); @@ -67,8 +65,8 @@ class SOFA_HELPER_API ColorMap unsigned int i = (unsigned int)(e); if (i>=map->entries.size()-1) return map->entries.back(); - Color c1 = map->entries[i]; - const Color c2 = map->entries[i+1]; + const auto& c1 = map->entries[i]; + const auto& c2 = map->entries[i+1]; return c1+(c2-c1)*(e-i); } protected: @@ -93,9 +91,9 @@ class SOFA_HELPER_API ColorMap void setColorScheme(const std::string& colorScheme) { m_colorScheme = colorScheme; } unsigned int getNbColors() const { return (unsigned int) entries.size(); } - Color getColor(unsigned int i) { + type::RGBAColor getColor(unsigned int i) { if (i < entries.size()) return entries[i]; - return Color(0.f, 0.f, 0.f, 0.f); + return type::RGBAColor(0.f, 0.f, 0.f, 0.f); } static ColorMap* getDefault(); @@ -110,7 +108,8 @@ class SOFA_HELPER_API ColorMap } } - Color3 hsv2rgb(const Color3 &hsv); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + type::Vec3f hsv2rgb(const type::Vec3f& hsv); inline friend std::ostream& operator << (std::ostream& out, const ColorMap& m ) { diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp b/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp index d5f67d51a624..7e0e88208dd7 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.cpp @@ -26,6 +26,7 @@ #include #include +#include using namespace sofa::type::pairwise; @@ -178,6 +179,16 @@ RGBAColor RGBAColor::fromVec4(const type::fixed_array& color) return RGBAColor(float(color[0]), float(color[1]), float(color[2]), float(color[3])); } +RGBAColor RGBAColor::fromVec4(const type::Vec4f& color) +{ + return RGBAColor(float(color[0]), float(color[1]), float(color[2]), float(color[3])); +} + +RGBAColor RGBAColor::fromVec4(const type::Vec4d& color) +{ + return RGBAColor(float(color[0]), float(color[1]), float(color[2]), float(color[3])); +} + /// This function remove the leading space in the stream. static std::istream& trimInitialSpaces(std::istream& in) { diff --git a/Sofa/framework/Type/src/sofa/type/RGBAColor.h b/Sofa/framework/Type/src/sofa/type/RGBAColor.h index f649f2ef8f61..76a44dc3fb0c 100644 --- a/Sofa/framework/Type/src/sofa/type/RGBAColor.h +++ b/Sofa/framework/Type/src/sofa/type/RGBAColor.h @@ -65,6 +65,10 @@ class SOFA_TYPE_API RGBAColor static RGBAColor fromVec4(const type::fixed_array& color); SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() static RGBAColor fromVec4(const type::fixed_array& color); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static RGBAColor fromVec4(const Vec4f& color); + SOFA_ATTRIBUTE_DEPRECATED__RGBACOLOR_AS_FIXEDARRAY() + static RGBAColor fromVec4(const Vec4d& color); static RGBAColor fromString(const std::string& str); static RGBAColor fromFloat(float r, float g, float b, float a); @@ -209,6 +213,17 @@ constexpr RGBAColor operator+(const RGBAColor& l, const RGBAColor& r) return sofa::type::pairwise::operator+(l, r); } +constexpr RGBAColor operator/(const RGBAColor& l, const float div) +{ + RGBAColor result{}; + for (std::size_t i = 0; i < 4; ++i) + { + result[i] = l[i] / div; + } + return result; +} + + constexpr RGBAColor g_white {1.0f,1.0f,1.0f,1.0f}; constexpr RGBAColor g_black {0.0f,0.0f,0.0f,1.0f}; constexpr RGBAColor g_red {1.0f,0.0f,0.0f,1.0f}; From 3fadc10492662a63eab725fa45894f2c5b3fe9bd Mon Sep 17 00:00:00 2001 From: Alex Bilger Date: Wed, 6 Dec 2023 01:07:27 +0100 Subject: [PATCH 54/60] [ODESolver.Backward] Convert double to SReal in NewmarkImplicitSolver (#4341) * [ODESolver.Backward] Convert double to SReal in NewmarkImplicitSolver * Adapt default values to the new type SReal --- .../backward/NewmarkImplicitSolver.cpp | 23 +++++++++++-------- .../backward/NewmarkImplicitSolver.h | 10 ++++---- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.cpp b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.cpp index be829e69fb60..62d1ade2042c 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.cpp +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.cpp @@ -42,11 +42,16 @@ using namespace sofa::defaulttype; using namespace core::behavior; NewmarkImplicitSolver::NewmarkImplicitSolver() - : d_rayleighStiffness(initData(&d_rayleighStiffness,0.0,"rayleighStiffness","Rayleigh damping coefficient related to stiffness") ) - , d_rayleighMass( initData(&d_rayleighMass,0.0,"rayleighMass","Rayleigh damping coefficient related to mass")) - , d_velocityDamping( initData(&d_velocityDamping,0.0,"vdamping","Velocity decay coefficient (no decay if null)") ) - , d_gamma( initData(&d_gamma, 0.5, "gamma", "Newmark scheme gamma coefficient")) - , d_beta( initData(&d_beta, 0.25, "beta", "Newmark scheme beta coefficient") ) + : d_rayleighStiffness(initData(&d_rayleighStiffness, 0_sreal, + "rayleighStiffness", + "Rayleigh damping coefficient related to stiffness")) + , d_rayleighMass(initData(&d_rayleighMass, 0_sreal, "rayleighMass", + "Rayleigh damping coefficient related to mass")) + , d_velocityDamping(initData(&d_velocityDamping, 0_sreal, "vdamping", + "Velocity decay coefficient (no decay if null)")) + , d_gamma(initData(&d_gamma, 0.5_sreal, "gamma", + "Newmark scheme gamma coefficient")) + , d_beta(initData(&d_beta, 0.25_sreal, "beta", "Newmark scheme beta coefficient")) , d_threadSafeVisitor(initData(&d_threadSafeVisitor, false, "threadSafeVisitor", "If true, do not use realloc and free visitors in fwdInteractionForceField.")) { cpt=0; @@ -70,10 +75,10 @@ void NewmarkImplicitSolver::solve(const core::ExecParams* params, SReal dt, sofa const SReal h = dt; - const double gamma = d_gamma.getValue(); - const double beta = d_beta.getValue(); - const double rM = d_rayleighMass.getValue(); - const double rK = d_rayleighStiffness.getValue(); + const SReal gamma = d_gamma.getValue(); + const SReal beta = d_beta.getValue(); + const SReal rM = d_rayleighMass.getValue(); + const SReal rK = d_rayleighStiffness.getValue(); // 1. Initialize a_t and to store it as a vecId to be used in the resolution of this solver (using as well old xand v) // Once we have a_{t+dt} we can update the new x and v. diff --git a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.h b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.h index 52ac563b514a..fec55b134817 100644 --- a/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.h +++ b/Sofa/Component/ODESolver/Backward/src/sofa/component/odesolver/backward/NewmarkImplicitSolver.h @@ -56,12 +56,12 @@ class SOFA_COMPONENT_ODESOLVER_BACKWARD_API NewmarkImplicitSolver : public sofa: public: SOFA_CLASS(NewmarkImplicitSolver, sofa::core::behavior::OdeSolver); - Data d_rayleighStiffness; ///< Rayleigh damping coefficient related to stiffness - Data d_rayleighMass; ///< Rayleigh damping coefficient related to mass - Data d_velocityDamping; ///< Velocity decay coefficient (no decay if null) + Data d_rayleighStiffness; ///< Rayleigh damping coefficient related to stiffness + Data d_rayleighMass; ///< Rayleigh damping coefficient related to mass + Data d_velocityDamping; ///< Velocity decay coefficient (no decay if null) - Data d_gamma; ///< Newmark scheme gamma coefficient - Data d_beta; ///< Newmark scheme beta coefficient + Data d_gamma; ///< Newmark scheme gamma coefficient + Data d_beta; ///< Newmark scheme beta coefficient Data d_threadSafeVisitor; ///< If true, do not use realloc and free visitors in fwdInteractionForceField. From 058f9d4db9ed111d02829d0022c10f4082295db3 Mon Sep 17 00:00:00 2001 From: Hugo Date: Thu, 7 Dec 2023 02:36:57 +0100 Subject: [PATCH 55/60] [SolidMechanics] Implement buildStiffnessMatrix for PolynomialSpringsFF (#4301) * [SolidMechanics] Implement buildStiffnessMatrix for PolynomialSpringsForceField * Remove timer --------- Co-authored-by: Alex Bilger --- .../spring/PolynomialSpringsForceField.h | 2 + .../spring/PolynomialSpringsForceField.inl | 69 ++++++++++++++++++- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.h b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.h index 7e5e085e2db4..057c75e5a980 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.h +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.h @@ -127,6 +127,8 @@ class PolynomialSpringsForceField : public core::behavior::PairInteractionForceF /// Brings ForceField contribution to the global system stiffness matrix. virtual void addKToMatrix(const core::MechanicalParams* mparams, const core::behavior::MultiMatrixAccessor* matrix) override; + void buildStiffnessMatrix(core::behavior::StiffnessMatrix* matrix) override; + void buildDampingMatrix(core::behavior::DampingMatrix* /*matrix*/) final; virtual void draw(const core::visual::VisualParams* vparams) override; diff --git a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.inl b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.inl index 404401f90016..3f5b9d9fab29 100644 --- a/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.inl +++ b/Sofa/Component/SolidMechanics/Spring/src/sofa/component/solidmechanics/spring/PolynomialSpringsForceField.inl @@ -60,7 +60,6 @@ PolynomialSpringsForceField::PolynomialSpringsForceField(MechanicalSt { } - template void PolynomialSpringsForceField::bwdInit() { @@ -394,8 +393,6 @@ void PolynomialSpringsForceField::draw(const core::visual::VisualPara } - - template void PolynomialSpringsForceField::addKToMatrix(const core::MechanicalParams* mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix ) @@ -461,6 +458,72 @@ void PolynomialSpringsForceField::addKToMatrix(const core::Mechanical } } +template +void PolynomialSpringsForceField::buildStiffnessMatrix(core::behavior::StiffnessMatrix* matrix) +{ + unsigned int firstIndex = 0; + unsigned int secondIndex = 0; + + if (this->mstate1 == this->mstate2) + { + auto dfdx = matrix->getForceDerivativeIn(this->mstate1.get()) + .withRespectToPositionsIn(this->mstate1.get()); + + for (unsigned int index = 0; index < m_firstObjectIndices.size(); index++) + { + firstIndex = m_firstObjectIndices[index]; + secondIndex = m_secondObjectIndices[index]; + const JacobianMatrix& jacobMatrix = m_differential[index]; + + for(unsigned int i = 0; i < m_dimension; i++) + { + for (unsigned int j = 0; j < m_dimension; j++) + { + Real stiffnessDeriv = jacobMatrix[i][j]; + dfdx(m_dimension * firstIndex + i, m_dimension * firstIndex + j) += - stiffnessDeriv; + dfdx(m_dimension * firstIndex + i, m_dimension * secondIndex + j) += stiffnessDeriv; + dfdx(m_dimension * secondIndex + i, m_dimension * firstIndex + j) += stiffnessDeriv; + dfdx(m_dimension * secondIndex + i, m_dimension * secondIndex + j) += - stiffnessDeriv; + } + } + } + } + else + { + auto* m1 = this->mstate1.get(); + auto* m2 = this->mstate2.get(); + + auto df1_dx1 = matrix->getForceDerivativeIn(m1).withRespectToPositionsIn(m1); + auto df1_dx2 = matrix->getForceDerivativeIn(m1).withRespectToPositionsIn(m2); + auto df2_dx1 = matrix->getForceDerivativeIn(m2).withRespectToPositionsIn(m1); + auto df2_dx2 = matrix->getForceDerivativeIn(m2).withRespectToPositionsIn(m2); + + df1_dx1.checkValidity(this); + df1_dx2.checkValidity(this); + df2_dx1.checkValidity(this); + df2_dx2.checkValidity(this); + + for (unsigned int index = 0; index < m_firstObjectIndices.size(); index++) + { + firstIndex = m_firstObjectIndices[index]; + secondIndex = m_secondObjectIndices[index]; + const JacobianMatrix& jacobMatrix = m_differential[index]; + + for(unsigned int i = 0; i < m_dimension; i++) + { + for (unsigned int j = 0; j < m_dimension; j++) + { + Real stiffnessDeriv = jacobMatrix[i][j]; + df1_dx1(m_dimension * firstIndex + i, m_dimension * firstIndex + j) += -stiffnessDeriv; + df1_dx2(m_dimension * firstIndex + i, m_dimension * secondIndex + j) += stiffnessDeriv; + df2_dx1(m_dimension * secondIndex + i, m_dimension * firstIndex + j) += stiffnessDeriv; + df2_dx2(m_dimension * secondIndex + i, m_dimension * secondIndex + j) += -stiffnessDeriv; + } + } + } + } +} + template void PolynomialSpringsForceField::buildDampingMatrix(core::behavior::DampingMatrix*) { From 7272629546545b4b9ab2238c3e3a9f4a1704cf72 Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Fri, 8 Dec 2023 22:26:35 +0900 Subject: [PATCH 56/60] [ODESolver] Fix compilation with SOFA_NO_VMULTIOP (#4325) fix when SOFA_NO_VMULTIOP is defined Co-authored-by: erik pernod --- .../odesolver/forward/CentralDifferenceSolver.cpp | 4 ++-- .../src/sofa/component/odesolver/forward/EulerSolver.cpp | 8 ++++---- .../component/odesolver/forward/RungeKutta2Solver.cpp | 4 ++-- .../component/odesolver/forward/RungeKutta4Solver.cpp | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/CentralDifferenceSolver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/CentralDifferenceSolver.cpp index 06b9d39d42c0..3ed6e8202e91 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/CentralDifferenceSolver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/CentralDifferenceSolver.cpp @@ -103,9 +103,9 @@ void CentralDifferenceSolver::solve(const core::ExecParams* params, SReal dt, so { #ifdef SOFA_NO_VMULTIOP // unoptimized version vel2.eq( vel, dx, dt ); // vel = vel + dt M^{-1} ( P_n - K u_n ) - mop.solveConstraint(vel2, core::ConstraintParams::ConstOrder::VEL); + mop.solveConstraint(vel2,core::ConstraintOrder::VEL); pos2.eq( pos, vel2, dt ); // pos = pos + h vel - mop.solveConstraint(pos2, core::ConstraintParams::ConstOrder::POS); + mop.solveConstraint(pos2,core::ConstraintOrder::POS); #else // single-operation optimization diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp index 59a9e6d7f90f..97fb91c7c889 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/EulerSolver.cpp @@ -135,10 +135,10 @@ void EulerExplicitSolver::updateState(sofa::simulation::common::VectorOperations //newPos = pos + newVel * dt newVel.eq(vel, acc.id(), dt); - mop->solveConstraint(newVel, core::ConstraintParams::ConstOrder::VEL); + mop->solveConstraint(newVel,core::ConstraintOrder::VEL); newPos.eq(pos, newVel, dt); - mop->solveConstraint(newPos, core::ConstraintParams::ConstOrder::POS); + mop->solveConstraint(newPos,core::ConstraintOrder::POS); } else { @@ -146,10 +146,10 @@ void EulerExplicitSolver::updateState(sofa::simulation::common::VectorOperations //newVel = vel + acc * dt newPos.eq(pos, vel, dt); - mop->solveConstraint(newPos, core::ConstraintParams::ConstOrder::POS); + mop->solveConstraint(newPos,core::ConstraintOrder::POS); newVel.eq(vel, acc.id(), dt); - mop->solveConstraint(newVel, core::ConstraintParams::ConstOrder::VEL); + mop->solveConstraint(newVel,core::ConstraintOrder::VEL); } #else // single-operation optimization { diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta2Solver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta2Solver.cpp index 0b3eb389aeed..4e75919e1a55 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta2Solver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta2Solver.cpp @@ -91,9 +91,9 @@ void RungeKutta2Solver::solve(const core::ExecParams* params, SReal dt, sofa::co // Use the derivative at newX, newV to update the state #ifdef SOFA_NO_VMULTIOP // unoptimized version pos2.eq(pos,newV,dt); - solveConstraint(dt,pos2,core::ConstraintParams::ConstOrder::POS); + mop.solveConstraint(pos2,core::ConstraintOrder::POS); vel2.eq(vel,acc,dt); - solveConstraint(dt,vel2,core::ConstraintParams::ConstOrder::VEL); + mop.solveConstraint(vel2,core::ConstraintOrder::VEL); #else // single-operation optimization { typedef core::behavior::BaseMechanicalState::VMultiOp VMultiOp; diff --git a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta4Solver.cpp b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta4Solver.cpp index 30ec32ed5555..bdd8b21795d5 100644 --- a/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta4Solver.cpp +++ b/Sofa/Component/ODESolver/Forward/src/sofa/component/odesolver/forward/RungeKutta4Solver.cpp @@ -160,9 +160,9 @@ void RungeKutta4Solver::solve(const core::ExecParams* params, SReal dt, sofa::co pos2.peq(k3v,stepBy3); vel2.peq(k3a,stepBy3); pos2.peq(k4v,stepBy6); - solveConstraint(dt, pos2, core::ConstraintParams::ConstOrder::POS); + mop.solveConstraint(pos2, core::ConstraintOrder::POS); vel2.peq(k4a,stepBy6); - solveConstraint(dt, vel2, core::ConstraintParams::ConstOrder::VEL); + mop.solveConstraint(vel2, core::ConstraintOrder::VEL); #else // single-operation optimization { typedef core::behavior::BaseMechanicalState::VMultiOp VMultiOp; From da70359feb76e03393ca5d43bdb156417bf78e3d Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Fri, 8 Dec 2023 22:27:56 +0900 Subject: [PATCH 57/60] [image] image_gui to compile with Qt6 (#4330) image_gui compiling with qt6 Co-authored-by: Hugo --- applications/plugins/image/image_gui/CMakeLists.txt | 1 - applications/plugins/image/image_gui/HistogramWidget.h | 4 ++-- applications/plugins/image/image_gui/ImagePlaneWidget.h | 8 ++++---- .../image/imagetoolbox/imagetoolboxcentralwidget.h | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/applications/plugins/image/image_gui/CMakeLists.txt b/applications/plugins/image/image_gui/CMakeLists.txt index 146d0e8f16b0..c08ae5d1f95f 100644 --- a/applications/plugins/image/image_gui/CMakeLists.txt +++ b/applications/plugins/image/image_gui/CMakeLists.txt @@ -29,7 +29,6 @@ if (NOT Qt5Core_FOUND) find_package(Qt6 COMPONENTS Core CoreTools REQUIRED QUIET) if (Qt6Core_FOUND) qt6_wrap_cpp(MOC_FILES ${MOC_HEADER_FILES}) - message(FATAL_ERROR "Image_gui is not compatible with Qt6 yet.") # to remove once image_gui has been updated endif() # else() should never happened as it would already break in Sofa.GUI.Qt endif() diff --git a/applications/plugins/image/image_gui/HistogramWidget.h b/applications/plugins/image/image_gui/HistogramWidget.h index be53b8bab475..78e523a06da0 100644 --- a/applications/plugins/image/image_gui/HistogramWidget.h +++ b/applications/plugins/image/image_gui/HistogramWidget.h @@ -86,7 +86,7 @@ class THistogramSetting: public HistogramSetting label3=new QLabel(parent); QHBoxLayout *layout = new QHBoxLayout(parent); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(label1); layout->addStretch(); layout->addWidget(label2); @@ -268,7 +268,7 @@ class HistogramOptionWidget: public QWidget label->setNum(0); QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(10); layout->addWidget(labelName); layout->addWidget(slider); diff --git a/applications/plugins/image/image_gui/ImagePlaneWidget.h b/applications/plugins/image/image_gui/ImagePlaneWidget.h index a80d205b2cf2..21b44730d1ca 100644 --- a/applications/plugins/image/image_gui/ImagePlaneWidget.h +++ b/applications/plugins/image/image_gui/ImagePlaneWidget.h @@ -159,9 +159,9 @@ public slots: void fitInView() // modified version of original fitinview (no margin) { - QRectF unity = this->matrix().mapRect(QRectF(0, 0, 1, 1)); + QRectF unity = this->transform().mapRect(QRectF(0, 0, 1, 1)); scale(1 / unity.width(), 1 / unity.height()); - QRectF sceneRect = this->matrix().mapRect(roi); + QRectF sceneRect = this->transform().mapRect(roi); scale(viewport()->rect().width() / sceneRect.width(), viewport()->rect().height() / sceneRect.height()); centerOn(roi.center()); } @@ -224,7 +224,7 @@ public slots: else { scene->P1=pt; emit cursorChangedX(pt.x()); emit cursorChangedY(pt.y()); Render ();} } - void wheelEvent (QWheelEvent *wheelev) override { emit wheelevent((wheelev->delta()>0)?1:-1); } + void wheelEvent (QWheelEvent *wheelev) override { emit wheelevent((wheelev->angleDelta().y()>0)?1:-1); } ImagePlaneGraphScene * scene; QRectF roi; @@ -438,7 +438,7 @@ class ImagePlaneOptionWidget: public QWidget QObject::connect(this,SIGNAL(toggled(bool)),label,SLOT(setVisible(bool))); QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(10); layout->addWidget(toggle); layout->addWidget(slider); diff --git a/applications/plugins/image/imagetoolbox/imagetoolboxcentralwidget.h b/applications/plugins/image/imagetoolbox/imagetoolboxcentralwidget.h index edd274227a19..5506312d2f71 100644 --- a/applications/plugins/image/imagetoolbox/imagetoolboxcentralwidget.h +++ b/applications/plugins/image/imagetoolbox/imagetoolboxcentralwidget.h @@ -87,7 +87,7 @@ class SOFA_IMAGE_GUI_API ImageToolBoxOptionCentralWidget: public QWidget QObject::connect(slider,SIGNAL(valueChanged(int)),this,SIGNAL(valueChanged())); QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(10); //layout->add(toggle); layout->addWidget(slider); From 384d495c10ac33d3d88e38dd7b79b45848cfc13f Mon Sep 17 00:00:00 2001 From: Frederick Roy Date: Sat, 9 Dec 2023 01:10:46 +0900 Subject: [PATCH 58/60] [Simulation.Core] Deprecate LocalStorage feature (#4327) * remove unused local storage feat * deprecate localstorage and impl * restore and deprecate functions using localstorage --------- Co-authored-by: Hugo --- .../Core/src/sofa/simulation/BaseMechanicalVisitor.h | 6 ++++-- .../Core/src/sofa/simulation/CactusStackStorage.h | 3 +++ .../Simulation/Core/src/sofa/simulation/LocalStorage.h | 5 +++++ .../Simulation/Core/src/sofa/simulation/Visitor.h | 2 ++ .../Simulation/Core/src/sofa/simulation/config.h.in | 10 ++++++++++ .../Simulation/Core/src/sofa/simulation/fwd.h | 1 - 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.h index a52ae7f2b50d..bd25f9e25b7c 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/BaseMechanicalVisitor.h @@ -79,7 +79,8 @@ class SOFA_SIMULATION_CORE_API BaseMechanicalVisitor : public Visitor /// Parallel version of processNodeTopDown. /// This method calls the fwd* methods during the forward traversal. You typically do not overload it. - Result processNodeTopDown(simulation::Node* node, LocalStorage* stack) override; + SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() + Result processNodeTopDown(simulation::Node * node, LocalStorage * stack) override; /// Process the OdeSolver virtual Result fwdOdeSolver(simulation::Node* /*node*/, sofa::core::behavior::OdeSolver* /*solver*/); @@ -169,7 +170,8 @@ class SOFA_SIMULATION_CORE_API BaseMechanicalVisitor : public Visitor /// Parallel version of processNodeBottomUp. /// This method calls the bwd* methods during the backward traversal. You typically do not overload it. - void processNodeBottomUp(simulation::Node* /*node*/, LocalStorage* stack) override; + SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() + void processNodeBottomUp(simulation::Node* /*node*/, LocalStorage * stack) override; /// Process the BaseMechanicalState when it is not mapped from parent level virtual void bwdMechanicalState(simulation::Node* /*node*/,sofa::core::behavior::BaseMechanicalState* /*mm*/); diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/CactusStackStorage.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/CactusStackStorage.h index 6afb0cca3dfa..4bb1222f39f3 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/CactusStackStorage.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/CactusStackStorage.h @@ -26,6 +26,8 @@ #include #include +SOFA_HEADER_DEPRECATED_LOCALSTORAGE() + namespace sofa { @@ -36,6 +38,7 @@ namespace simulation /// Cactus Stack implementation of LocalStorage. /// See http://www.nist.gov/dads/HTML/cactusstack.html +SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() class SOFA_SIMULATION_CORE_API CactusStackStorage : public simulation::LocalStorage { protected: diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/LocalStorage.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/LocalStorage.h index f06d2a3c5284..2df86d938c29 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/LocalStorage.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/LocalStorage.h @@ -22,6 +22,10 @@ #ifndef SOFA_SIMULATION_TREE_LOCALSTORAGE_H #define SOFA_SIMULATION_TREE_LOCALSTORAGE_H +#include + +SOFA_HEADER_DEPRECATED_LOCALSTORAGE() + namespace sofa { @@ -32,6 +36,7 @@ namespace simulation class Visitor; /// Abstract class allowing actions to store local data as a stack while traversing the graph. +SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() class LocalStorage { protected: diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/Visitor.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/Visitor.h index 42d0fb245e71..90b09b3da914 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/Visitor.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/Visitor.h @@ -160,10 +160,12 @@ class SOFA_SIMULATION_CORE_API Visitor /// Callback method called when decending to a new node. Recursion will stop if this method returns RESULT_PRUNE /// This version is offered a LocalStorage to store temporary data + SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() virtual Result processNodeTopDown(simulation::Node* node, LocalStorage*) { return processNodeTopDown(node); } /// Callback method called after child node have been processed and before going back to the parent node. /// This version is offered a LocalStorage to store temporary data + SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() virtual void processNodeBottomUp(simulation::Node* node, LocalStorage*) { processNodeBottomUp(node); } typedef sofa::core::objectmodel::Tag Tag; diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in b/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in index dce81618ee49..a949327fc2c6 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/config.h.in @@ -238,3 +238,13 @@ SOFA_ATTRIBUTE_DEPRECATED( \ #define SOFA_HEADER_DEPRECATED_PARALLELVISITORSCHEDULER() \ SOFA_DEPRECATED_HEADER_NOT_REPLACED("v23.12", "v24.06") #endif // SOFA_BUILD_SOFA_SIMULATION_CORE + +#ifdef SOFA_BUILD_SOFA_SIMULATION_CORE +#define SOFA_HEADER_DEPRECATED_LOCALSTORAGE() +#define SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() +#else +#define SOFA_HEADER_DEPRECATED_LOCALSTORAGE() \ + SOFA_DEPRECATED_HEADER_NOT_REPLACED("v23.12", "v24.06") +#define SOFA_ATTRIBUTE_DEPRECATED_LOCALSTORAGE() \ + SOFA_ATTRIBUTE_DEPRECATED("v23.12", "v24.06", "LocalStorage feature was seemingly not used so it has been deprecated.") +#endif // SOFA_BUILD_SOFA_SIMULATION_CORE diff --git a/Sofa/framework/Simulation/Core/src/sofa/simulation/fwd.h b/Sofa/framework/Simulation/Core/src/sofa/simulation/fwd.h index 69e091bca8a7..ca6ae46f75b4 100644 --- a/Sofa/framework/Simulation/Core/src/sofa/simulation/fwd.h +++ b/Sofa/framework/Simulation/Core/src/sofa/simulation/fwd.h @@ -46,7 +46,6 @@ namespace sofa::simulation */ SOFA_SIMULATION_CORE_API Simulation* getSimulation(); - class LocalStorage; class MutationListener; class Visitor; From d33ae528aa1c12b4445845b83e235e56f5083fd9 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 11 Dec 2023 11:55:47 +0100 Subject: [PATCH 59/60] [GitHub] Add a python-based action managing discussions (#4268) * [GitHub] Add a python-based action managing discussions * add python script * make action triggered on labels * simplify action * add python-graphql-client dependency * add dateutil dependency * activate script limited on 1 topic per activation and remove cron temporarily * add verbosity on discussions, add cron & dispatch trigger, remove trigger on label changes * Rename action as: Stale GitHub Discussions * Apply suggestions from code review Co-authored-by: Alex Bilger --------- Co-authored-by: Alex Bilger --- .../workflows/stale_github_discussions.yml | 32 ++ scripts/comment-close-old-discussions.py | 335 ++++++++++++++++++ 2 files changed, 367 insertions(+) create mode 100644 .github/workflows/stale_github_discussions.yml create mode 100644 scripts/comment-close-old-discussions.py diff --git a/.github/workflows/stale_github_discussions.yml b/.github/workflows/stale_github_discussions.yml new file mode 100644 index 000000000000..cfac73e28d01 --- /dev/null +++ b/.github/workflows/stale_github_discussions.yml @@ -0,0 +1,32 @@ +name: Stale GitHub Discussions + +on: + workflow_dispatch: + schedule: + - cron: '0 6 * * 1' # Every Monday at 6:00 AM UTC (8:00 AM CET) + +jobs: + run: + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.10' # Use the desired Python version + + - name: Install dependencies + run: | + pip install python-graphql-client + pip install python-dateutil + working-directory: ${{ github.workspace }} + + - name: Run script comment-close-old-discussions.py + run: | + python scripts/comment-close-old-discussions.py + working-directory: ${{ github.workspace }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/scripts/comment-close-old-discussions.py b/scripts/comment-close-old-discussions.py new file mode 100644 index 000000000000..e7bb28baeed6 --- /dev/null +++ b/scripts/comment-close-old-discussions.py @@ -0,0 +1,335 @@ +#!python + +# DEPENDENCIES +# python3 -m pip install python-graphql-client + +#Ref : Action in python https://www.python-engineer.com/posts/run-python-github-actions/ + + +#TEST steps: +# - add cron & dispatch trigger, remove trigger on label changes (yml) +# - test with only one entry (break) +# - remove break +# - after 1st of December 2023, remove the temporary layer + +import os +import sys +import json +from datetime import datetime, timedelta, date +from python_graphql_client import GraphqlClient +from dateutil.relativedelta import relativedelta + + +client = GraphqlClient(endpoint="https://api.github.com/graphql") +github_token = os.environ['GITHUB_TOKEN'] + + +# List of the repository to scan +repos=[['sofa-framework','sofa']] + + +# Format the reference date (with which the last reply will be compared) +# Today +date_today = date.today() +# warning delay = 2-month delay for warning +delay_warning = relativedelta(months = 2) +date_reference_warning = date_today - delay_warning +# closing delay = 2+2.5-month delay for closing +delay_closing = relativedelta(months = 2) + relativedelta(weeks = 1) +date_reference_closing = date_today - delay_closing + + +# List of reviewers on GitHub Discussions +reviewer_logins=[["alxbilger"],["hugtalbot"],["bakpaul"],["fredroy"],["epernod"],["damienmarchal"],["VannesteFelix"],["EulalieCoevoet"],["github-actions"]] + + +# Check if the "createdAt" is older than the "date_reference" +def isOlderThan(date_reference, createdAt): + # Format date of creation YYYY-MM-DD + creation_date = createdAt[:-10] + creation_date = datetime.strptime(creation_date, '%Y-%m-%d') + + if creation_date.date() > date_reference: + return False + else : + return True + +# Returns true of the date "createdAt" is more than the warning delay +def isToBeWarned(createdAt): + return isOlderThan(date_reference_warning, createdAt) + + +# Returns true of the date "createdAt" is more than the closing delay +def isToBeClosed(createdAt): + return isOlderThan(date_reference_closing, createdAt) + + + +def computeListOfDiscussionToProcess(): + for repo in repos: + + owner = repo[0] + name = repo[1] + + has_next_page = True + after_cursor = None + + to_be_warned_discussion_number = [] + to_be_warned_discussion_id = [] + to_be_warned_discussion_author = [] + + to_be_closed_discussion_number = [] + to_be_closed_discussion_id = [] + to_be_closed_discussion_author = [] + + while has_next_page: + # Trigger the query on discussions + data = client.execute( + query = make_query_discussions(owner, name, after_cursor), + headers = {"Authorization": "Bearer {}".format(github_token)}, + ) + + # Process each discussion + for discussion in data["data"]["repository"]["discussions"]["nodes"]: + + # Save original author of the discussion + discussionAuthor = discussion["author"]["login"] + + # Detect the last comment + lastCommentId = len(discussion["comments"]["nodes"]) - 1 + + # Pass to the next discussion item, if no comment in the discussion + if(lastCommentId < 0): + continue + + lastReplyOnLastComment = len(discussion["comments"]["nodes"][lastCommentId]["replies"]["nodes"]) - 1 + + # No replies on the last comment + if(lastReplyOnLastComment < 0): + author = discussion["comments"]["nodes"][lastCommentId]["author"]["login"] + dateLastMessage = discussion["comments"]["nodes"][lastCommentId]["createdAt"] + # Select the last reply of the last comment + else: + author = discussion["comments"]["nodes"][lastCommentId]["replies"]["nodes"][lastReplyOnLastComment]["author"]["login"] + dateLastMessage = discussion["comments"]["nodes"][lastCommentId]["replies"]["nodes"][lastReplyOnLastComment]["createdAt"] + + authorAsList = [author] + + # Check if author is indeed a reviewer + if authorAsList in reviewer_logins: + #Check dates + if isToBeClosed(dateLastMessage) == True: + to_be_closed_discussion_number.append(discussion["number"]) + to_be_closed_discussion_id.append(discussion["id"]) + to_be_closed_discussion_author.append(discussionAuthor) + elif isToBeWarned(dateLastMessage) == True and author != "github-actions": + to_be_warned_discussion_number.append(discussion["number"]) + to_be_warned_discussion_id.append(discussion["id"]) + to_be_warned_discussion_author.append(discussionAuthor) + + + # save if request has another page to browse and its cursor pointers + has_next_page = data["data"]["repository"]["discussions"]["pageInfo"]["hasNextPage"] + after_cursor = data["data"]["repository"]["discussions"]["pageInfo"]["endCursor"] + return [to_be_warned_discussion_number,to_be_warned_discussion_id,to_be_warned_discussion_author,to_be_closed_discussion_number,to_be_closed_discussion_id,to_be_closed_discussion_author] + + +# Query to access all discussions +def make_query_discussions(owner, name, after_cursor=None): + query = """ + query { + repository(owner: "%s" name: "%s") { + discussions(answered: false, first: 10, after:AFTER) { + totalCount + pageInfo { + hasNextPage + endCursor + } + nodes { + id + number + authorAssociation + author { + login + } + answer { + body + } + comments (first: 100) { + nodes { + createdAt + author { + login + } + replies (first: 100) { + nodes { + createdAt + author { + login + } + } + } + } + } + } + } + } + }""" % (owner, name) + return query.replace("AFTER", '"{}"'.format(after_cursor) if after_cursor else "null") + + + + +def make_github_warning_comment(discussion_id, discussion_author): + message = ":warning: :warning: :warning:
@"+str(discussion_author)+"
Feedback has been given to you by the project reviewers, however we have not received a response from you. Without further news in the coming weeks, this discussion will be automatically closed in order to keep this forum clean and fresh :seedling: Thank you for your understanding" + + query = """ + mutation { + addDiscussionComment(input: {body: "%s", discussionId: "%s"}) { + comment { + id + } + } + } +""" % (message, discussion_id) + return query + + + +def make_github_closing_comment(discussion_id, discussion_author): + message = ":warning: :warning: :warning:
@"+str(discussion_author)+"
In accordance with our forum management policy, the last reply is more than 4 months old and is therefore closed. Our objective is to keep the forum up to date and offer the best support experience.

Please feel free to reopen it if the topic is still active by providing us with an update. Please feel free to open a new thread at any time - we'll be happy to help where and when we can." + + query = """ + mutation { + addDiscussionComment(input: {body: "%s", discussionId: "%s"}) { + comment { + id + } + } + } +""" % (message, discussion_id) + return query + +def close_github_discussion(discussion_id): + + query = """ + mutation { + closeDiscussion(input: {discussionId: "%s"}) { + discussion { + id + } + } + } +""" % (discussion_id) + return + + +# ------- TO REMOVE !!!! --------- +def temporary_github_closing_comment(discussion_id, discussion_author): + message = ":warning: :warning: :warning:
@"+str(discussion_author)+"
We are setting a new forum management policy: topics like this one, in which the last reply is more than 4 months old, will automatically be closed. Without further news in the coming weeks, our bot will proceed to automatic closure, thus keeping this forum clean and fresh :seedling: Thank you for your understanding" + + query = """ + mutation { + addDiscussionComment(input: {body: "%s", discussionId: "%s"}) { + comment { + id + } + } + } +""" % (message, discussion_id) + return query +# -------------------------------- + + + + +#========================================================== +# STEPS computed by the script +#========================================================== +# 1 - get the discussion to be warned and closed +result = computeListOfDiscussionToProcess() +to_be_warned_discussion_number = result[0] +to_be_warned_discussion_id = result[1] +to_be_warned_discussion_author = result[2] +to_be_closed_discussion_number = result[3] +to_be_closed_discussion_id = result[4] +to_be_closed_discussion_author = result[5] +#========================================================== +# 2- do it using github API +if(len(to_be_warned_discussion_id)!=len(to_be_warned_discussion_author)): + print('Error: size of both vectors number/author for discussions to be warned is different') + exit(1) +if(len(to_be_closed_discussion_id)!=len(to_be_closed_discussion_author)): + print('Error: size of both vectors number/author for discussions to be closed is different') + exit(1) + +print("** Output lists **") +print("******************") +print("to_be_warned_discussion_number = "+str(to_be_warned_discussion_number) +print("to_be_warned_discussion_id = "+str(to_be_warned_discussion_id) +print("to_be_warned_discussion_author = "+str(to_be_warned_discussion_author) +print("to_be_closed_discussion_number = "+str(to_be_closed_discussion_number) +print("to_be_closed_discussion_id = "+str(to_be_closed_discussion_id) +print("to_be_closed_discussion_author = "+str(to_be_closed_discussion_author) +print("******************") + +#========================================================== +# WARNING step +for index, discussion_id in enumerate(to_be_warned_discussion_id): + print("to_be_warned_discussion_number[index] = "+str(to_be_warned_discussion_number[index])) + print("to_be_warned_discussion_author[index] = "+str(to_be_warned_discussion_author[index])) + print("discussion_id = "+str(discussion_id)) + # Warning comment + data = client.execute( + query = make_github_warning_comment( discussion_id, to_be_warned_discussion_author[index] ), + headers = {"Authorization": "Bearer {}".format(github_token)}, + ) + print(data) + break# ------- TO REMOVE !!!! + + +#========================================================== +# CLOSING step +# ------- TO REMOVE !!!! --------- +date_today = date.today() +date_end_temporary_message = date.fromisoformat('2023-12-01') +temporary_case = False + +if date_today > date_end_temporary_message: + temporary_case = False +else: + temporary_case = True + +if temporary_case: + print(str(date_end_temporary_message-date_today[:-9])+" days to go before end of temporary message") +# -------------------------------- + +for index, discussion_id in enumerate(to_be_closed_discussion_id): + print("to_be_closed_discussion_number[index] = "+str(to_be_closed_discussion_number[index])) + print("to_be_closed_discussion_author[index] = "+str(to_be_closed_discussion_author[index])) + print("discussion_id = "+str(discussion_id)) + # ------- TO REMOVE !!!! --------- + if temporary_case: + # Closing comment + data = client.execute( + query = temporary_github_closing_comment( discussion_id, to_be_closed_discussion_author[index] ), + headers = {"Authorization": "Bearer {}".format(github_token)}, + ) + print(data) + else: + # -------------------------------- + # Closing comment + data = client.execute( + query = make_github_closing_comment( discussion_id, to_be_closed_discussion_author[index] ), + headers = {"Authorization": "Bearer {}".format(github_token)}, + ) + print(data) + # Close discussion + data = client.execute( + query = close_github_discussion( discussion_id ), + headers = {"Authorization": "Bearer {}".format(github_token)}, + ) + print(data) + break# ------- TO REMOVE !!!! + +#========================================================== \ No newline at end of file From 9c9e377c7e148188e831d1617e9c3dec1ead4e91 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 11 Dec 2023 13:53:42 +0100 Subject: [PATCH 60/60] [github] quick fix for GHD script (#4347) --- scripts/comment-close-old-discussions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/comment-close-old-discussions.py b/scripts/comment-close-old-discussions.py index e7bb28baeed6..a25dffd59f2c 100644 --- a/scripts/comment-close-old-discussions.py +++ b/scripts/comment-close-old-discussions.py @@ -292,7 +292,7 @@ def temporary_github_closing_comment(discussion_id, discussion_author): # CLOSING step # ------- TO REMOVE !!!! --------- date_today = date.today() -date_end_temporary_message = date.fromisoformat('2023-12-01') +date_end_temporary_message = date.fromisoformat('2024-01-01') temporary_case = False if date_today > date_end_temporary_message: