Changed default normal. Identical cantilever results with panettaD

This commit is contained in:
iasonmanolas 2022-07-12 13:00:11 +03:00
parent 9d9f7dbacf
commit e70b4e9863
3 changed files with 255 additions and 170 deletions

View File

@ -48,10 +48,10 @@ if(${USE_POLYSCOPE})
add_subdirectory(${POLYSCOPE_SOURCE_DIR} ${POLYSCOPE_BINARY_DIR}) add_subdirectory(${POLYSCOPE_SOURCE_DIR} ${POLYSCOPE_BINARY_DIR})
add_compile_definitions(POLYSCOPE_DEFINED) add_compile_definitions(POLYSCOPE_DEFINED)
target_sources(${PROJECT_NAME} PUBLIC ${POLYSCOPE_SOURCE_DIR}/deps/imgui/imgui/misc/cpp/imgui_stdlib.cpp) target_sources(${PROJECT_NAME} PUBLIC ${POLYSCOPE_SOURCE_DIR}/deps/imgui/imgui/misc/cpp/imgui_stdlib.cpp)
if(${USE_POLYSCOPE})
message("Using polyscope here") message("Using polyscope..")
target_include_directories(${PROJECT_NAME} PUBLIC ${POLYSCOPE_SOURCE_DIR}/include)
target_link_libraries(${PROJECT_NAME} PUBLIC polyscope) target_link_libraries(${PROJECT_NAME} PUBLIC polyscope)
endif()
endif() endif()
##vcglib devel branch ##vcglib devel branch
@ -62,9 +62,6 @@ download_project(PROJ vcglib_devel
${UPDATE_DISCONNECTED_IF_AVAILABLE} ${UPDATE_DISCONNECTED_IF_AVAILABLE}
) )
add_subdirectory(${vcglib_devel_SOURCE_DIR} ${vcglib_devel_BINARY_DIR}) add_subdirectory(${vcglib_devel_SOURCE_DIR} ${vcglib_devel_BINARY_DIR})
#add_subdirectory("/home/iason/Coding/Libraries/vcglib" ${CMAKE_CURRENT_BINARY_DIR}/vcglib)
#target_include_directories(${PROJECT_NAME} PUBLIC "/home/iason/Coding/Libraries/vcglib")
target_sources(${PROJECT_NAME} PUBLIC ${vcglib_devel_SOURCE_DIR}/wrap/ply/plylib.cpp) target_sources(${PROJECT_NAME} PUBLIC ${vcglib_devel_SOURCE_DIR}/wrap/ply/plylib.cpp)
##matplot++ lib ##matplot++ lib
@ -90,27 +87,11 @@ download_project(PROJ threed-beam-fea
) )
add_subdirectory(${threed-beam-fea_SOURCE_DIR} ${threed-beam-fea_BINARY_DIR}) add_subdirectory(${threed-beam-fea_SOURCE_DIR} ${threed-beam-fea_BINARY_DIR})
##TBB find_package(Eigen3 3.4 REQUIRED)
set(TBB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/tbb)
download_project(PROJ TBB
GIT_REPOSITORY https://github.com/wjakob/tbb.git
GIT_TAG master
PREFIX ${EXTERNAL_DEPS_DIR}
BINARY_DIR ${TBB_BINARY_DIR}
${UPDATE_DISCONNECTED_IF_AVAILABLE}
)
option(TBB_BUILD_TESTS "Build TBB tests and enable testing infrastructure" OFF)
add_subdirectory(${TBB_SOURCE_DIR} ${TBB_BINARY_DIR})
link_directories(${TBB_BINARY_DIR})
###Eigen 3 NOTE: Eigen is required on the system the code is ran
find_package(Eigen3 3.3 REQUIRED)
if(MSVC) if(MSVC)
add_compile_definitions(_HAS_STD_BYTE=0) add_compile_definitions(_HAS_STD_BYTE=0)
endif(MSVC) endif(MSVC)
#link_directories(${CMAKE_CURRENT_LIST_DIR}/boost_graph/libs)
#set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
if(${MYSOURCES_STATIC_LINK}) if(${MYSOURCES_STATIC_LINK})
message("STATIC LINK MY SOURCES:" ${MYSOURCES_STATIC_LINK}) message("STATIC LINK MY SOURCES:" ${MYSOURCES_STATIC_LINK})
endif() endif()
@ -149,33 +130,56 @@ download_project(PROJ ENSMALLEN
PREFIX ${EXTERNAL_DEPS_DIR} PREFIX ${EXTERNAL_DEPS_DIR}
${UPDATE_DISCONNECTED_IF_AVAILABLE} ${UPDATE_DISCONNECTED_IF_AVAILABLE}
) )
# add_subdirectory(${ENSMALLEN_SOURCE_DIR} ${ENSMALLEN_BINARY_DIR})
# target_link_libraries(${PROJECT_NAME} INTERFACE ensmallen)
target_include_directories(${PROJECT_NAME} target_include_directories(${PROJECT_NAME}
PUBLIC ${ENSMALLEN_SOURCE_DIR}/include) PUBLIC ${ENSMALLEN_SOURCE_DIR}/include)
add_compile_definitions(USE_ENSMALLEN) add_compile_definitions(USE_ENSMALLEN)
#endif() #endif()
#Chrono #Chrono
#set(Chrono_DIR "/home/iason/Coding/Libraries/chrono-7.0.3/build/cmake")
set(Chrono_DIR "/home/iason/Coding/Libraries/chrono-7.0.3/build/cmake") set(Chrono_DIR "/home/iason/Coding/Libraries/chrono-7.0.3/build/cmake")
LIST(APPEND CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}/../Chrono/lib") #LIST(APPEND CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}/../Chrono/lib")
#set(Chrono_DIR "/home/iason/Coding/build/external dependencies/CHRONO-src/cmake") #find_package(Chrono #[[COMPONENTS FEA]]
find_package(Chrono #[[COMPONENTS FEA]] # CONFIG)
CONFIG) #if (NOT Chrono_FOUND)
if (NOT Chrono_FOUND) # message("Could not find Chrono or one of its required modules")
message("Could not find Chrono or one of its required modules") # return()
return() #endif()
#set_target_properties(${PROJECT_NAME} PROPERTIES
# COMPILE_FLAGS "${CHRONO_CXX_FLAGS} ${EXTRA_COMPILE_FLAGS}"
# COMPILE_DEFINITIONS "CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\""
# LINK_FLAGS "${CHRONO_LINKER_FLAGS}")
#target_link_libraries(${PROJECT_NAME} PRIVATE ${CHRONO_LIBRARIES})
target_include_directories(${PROJECT_NAME} PRIVATE ${CHRONO_INCLUDE_DIRS} #[["/home/iason/Coding/Libraries/chrono-7.0.3/src"]] #[["/usr/include/irrlicht"]] )
#target_link_directories(${PROJECT_NAME} PUBLIC "/home/iason/Coding/Libraries/chrono-7.0.3/build/Debug/lib/")
target_link_libraries(${PROJECT_NAME} PRIVATE "/home/iason/Coding/Libraries/chrono-7.0.3/build/Debug/lib/libChronoEngine.so" #[[ChronoEngine_irrlicht]])
#add_subdirectory("/home/iason/Coding/Projects/Approximating shapes with flat patterns/Elastic rods/ElasticRods")
#set(MESHFEM_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/meshfem)
#download_project(PROJ MESHFEM
# GIT_REPOSITORY https://github.com/MeshFEM/MeshFEM.git
# GIT_TAG 3847ffaeb6e9c4bbe15f0f81f5c773c7c481c059
# BINARY_DIR ${MESHFEM_BINARY_DIR}
# PREFIX ${EXTERNAL_DEPS_DIR}
# ${UPDATE_DISCONNECTED_IF_AVAILABLE}
#)
#add_subdirectory(${MESHFEM_SOURCE_DIR} ${MESHFEM_BINARY_DIR})
#target_link_libraries(${PROJECT_NAME} PUBLIC MeshFEM)
##target_include_directories(${PROJECT_NAME}
##PUBLIC ${MESHFEM_SOURCE_DIR}/include)
##add_compile_definitions(USE_ENSMALLEN)
##TBB
if(NOT TARGET tbb)
set(TBB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/tbb)
download_project(PROJ TBB
GIT_REPOSITORY https://github.com/wjakob/tbb.git
GIT_TAG master
PREFIX ${EXTERNAL_DEPS_DIR}
BINARY_DIR ${TBB_BINARY_DIR}
${UPDATE_DISCONNECTED_IF_AVAILABLE}
)
option(TBB_BUILD_TESTS "Build TBB tests and enable testing infrastructure" OFF)
add_subdirectory(${TBB_SOURCE_DIR} ${TBB_BINARY_DIR})
endif() endif()
set_target_properties(${PROJECT_NAME} PROPERTIES link_directories(${TBB_BINARY_DIR})
COMPILE_FLAGS "${CHRONO_CXX_FLAGS} ${EXTRA_COMPILE_FLAGS}"
COMPILE_DEFINITIONS "CHRONO_DATA_DIR=\"${CHRONO_DATA_DIR}\""
LINK_FLAGS "${CHRONO_LINKER_FLAGS}")
target_link_libraries(${PROJECT_NAME} PRIVATE ${CHRONO_LIBRARIES})
target_include_directories(${PROJECT_NAME} PRIVATE ${CHRONO_INCLUDE_DIRS})
#find_package(OpenMP REQUIRED)
#target_link_libraries(${PROJECT_NAME} OpenMP::OpenMP_CXX)
#target_include_directories(${PROJECT_NAME} OpenMP::OpenMP_CXX)
#message(STATUS "OpenMP_C_INCLUDE_DIRS: ${OpenMP_CXX_INCLUDE_DIRS}")

View File

@ -2,6 +2,7 @@
#include <unordered_set> #include <unordered_set>
#define MAT(mat, m, row, col) mat[m * col + row] #define MAT(mat, m, row, col) mat[m * col + row]
//#define EXPLICIT_BC
DER_leimer::DER_leimer() {} DER_leimer::DER_leimer() {}
@ -255,11 +256,12 @@ SimulationResults DER_leimer::constructSimulationResults(const std::shared_ptr<S
// pJob->pMesh->registerForDrawing(); // pJob->pMesh->registerForDrawing();
// polyscope::show(); // polyscope::show();
for (int vi = 0; vi < config->numVertices(); vi++) { for (int vi = 0; vi < config->numVertices(); vi++) {
std::cout << vi << " pos:" << config->vertices(vi, 0) << " " << config->vertices(vi, 1) // std::cout << vi << " pos:" << config->vertices(vi, 0) << " " << config->vertices(vi, 1)
<< " " << config->vertices(vi, 2) << std::endl; // << " " << config->vertices(vi, 2) << std::endl;
for (int dofi = 0; dofi < 3; dofi++) { for (int dofi = 0; dofi < 3; dofi++) {
const double initialPos_dofi = pJob->pMesh->vert[vi].cP()[dofi]; const double initialPos_dofi = pJob->pMesh->vert[vi].cP()[dofi];
const double displacement_dofi = config->vertices(vi, dofi) - initialPos_dofi; const double deformedPos_dofi = config->vertices(vi, dofi);
const double displacement_dofi = deformedPos_dofi - initialPos_dofi;
simulationResults.displacements[vi][dofi] = displacement_dofi; simulationResults.displacements[vi][dofi] = displacement_dofi;
} }
for (int dofi = 3; dofi < 6; dofi++) { for (int dofi = 3; dofi < 6; dofi++) {
@ -353,7 +355,7 @@ SimulationResults DER_leimer::executeSimulation(const std::shared_ptr<Simulation
// std::vector<Anchor> anchors{a0}; // std::vector<Anchor> anchors{a0};
const std::shared_ptr<VCGEdgeMesh> pMesh = pJob->pMesh; const std::shared_ptr<VCGEdgeMesh> pMesh = pJob->pMesh;
const int numRods = pMesh->EN(); const int numRods = pMesh->EN();
const int numVertsPerRod = 2; constexpr int numVertsPerRod = 2;
std::vector<int> vInd; std::vector<int> vInd;
vInd.reserve(pMesh->EN()); vInd.reserve(pMesh->EN());
for (int ei = 0; ei < pMesh->EN(); ei++) { for (int ei = 0; ei < pMesh->EN(); ei++) {
@ -391,12 +393,12 @@ SimulationResults DER_leimer::executeSimulation(const std::shared_ptr<Simulation
a.bary = edgeVi; a.bary = edgeVi;
a.position = ep->cP(edgeVi).ToEigenVector<Eigen::Vector3d>(); a.position = ep->cP(edgeVi).ToEigenVector<Eigen::Vector3d>();
a.normal = ep->cV(edgeVi)->cN().ToEigenVector<Eigen::Vector3d>(); a.normal = ep->cV(edgeVi)->cN().ToEigenVector<Eigen::Vector3d>();
a.k_pos = 1e4; a.k_pos = 1e6;
if (bc.second == fixedBC) { if (bc.second == fixedBC) {
a.k_dir = 0; a.k_dir = 0;
} else { } else {
assert(bc.second == rigidBC); assert(bc.second == rigidBC);
a.k_dir = 1e4; a.k_dir = 1e6;
} }
anchors.push_back(a); anchors.push_back(a);
} }
@ -569,7 +571,7 @@ bool DER_leimer::simulateOneStepGrid(RodConfig *config)
iter++; iter++;
if (iter > 50 /*&& forceResidual < 1e-5*/) { if (iter > 100 /*|| solverResidual < 1e-10*/ || forceResidual < 1e-5) {
// for (int vi = 0; vi < config->numVertices(); vi++) { // for (int vi = 0; vi < config->numVertices(); vi++) {
// std::cout << vi << " pos:" << config->vertices(vi, 0) << " " << config->vertices(vi, 1) // std::cout << vi << " pos:" << config->vertices(vi, 0) << " " << config->vertices(vi, 1)
// << " " << config->vertices(vi, 2) << std::endl; // << " " << config->vertices(vi, 2) << std::endl;
@ -594,11 +596,11 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
std::vector<Eigen::Triplet<int>> *Hu_index, std::vector<Eigen::Triplet<int>> *Hu_index,
std::vector<double> *Hu_value) std::vector<double> *Hu_value)
{ {
const bool computeHessian = [&]() { // const bool computeHessian = [&]() {
if (H_index && H_value && Ju && Hu_index && Hu_value) // if (H_index && H_value && Ju && Hu_index && Hu_value)
return true; // return true;
return false; // return false;
}(); // }();
const bool hasExternalForces = externalForces.rows() != 0; const bool hasExternalForces = externalForces.rows() != 0;
@ -624,8 +626,10 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
nterms += config.rods[i]->numSegments(); // stretching nterms += config.rods[i]->numSegments(); // stretching
nterms += 2 * njoints; // bending nterms += 2 * njoints; // bending
nterms += njoints; // twisting nterms += njoints; // twisting
#ifndef EXPLICIT_BC
if (params.anchorPoints) //?? if (params.anchorPoints) //??
nterms += 3 * config.rods[i]->numVertices(); nterms += 3 * config.rods[i]->numVertices();
#endif
// if (hasExternalForces) { // if (hasExternalForces) {
// nterms += config.rods[i]->numVertices(); // nterms += config.rods[i]->numVertices();
// } // }
@ -635,12 +639,14 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
} }
ndofs += config.numVertices() * 3; // DOF for vertices ndofs += config.numVertices() * 3; // DOF for vertices
//if (params.anchorPoints) if (params.anchorPoints)
// nterms += 3 * config.numVertices(); nterms += 3 * config.numVertices();
//if (params.gravityEnabled) //if (params.gravityEnabled)
// nterms += config.numVertices(); // floor force // nterms += config.numVertices(); // floor force
#ifndef EXPLICIT_BC
nterms += 4 * config.numAnchors(); nterms += 4 * config.numAnchors();
#endif
// Barycentric Coordinates are handled as DOF's since they can change when rods are sliding // Barycentric Coordinates are handled as DOF's since they can change when rods are sliding
int baryoffset = ndofs; int baryoffset = ndofs;
@ -669,8 +675,8 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
ndofs += 3 * config.numIntersections(); // euler angles as DOFs for intersections ndofs += 3 * config.numIntersections(); // euler angles as DOFs for intersections
r.resize(nterms); r.resize(nterms);
r.setConstant(std::numeric_limits<double>::infinity()); // r.setConstant(std::numeric_limits<double>::infinity());
// r.setZero(); r.setZero();
gravityPE = 0; gravityPE = 0;
gravityForces.resize(ndofs); gravityForces.resize(ndofs);
@ -864,16 +870,25 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
// const Eigen::Vector3d debug_forceLeimer = jacobianEntry * segr; // const Eigen::Vector3d debug_forceLeimer = jacobianEntry * segr;
// assert(debug_forceLeimer == debug_forcePanetta_j); // assert(debug_forceLeimer == debug_forcePanetta_j);
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
// Gradients for dEs/dx_i and dEs/dx_(i+1) // Gradients for dEs/dx_i and dEs/dx_(i+1)
// if (!pJob->constrainedVertices.contains(m1)) { #ifdef EXPLICIT_BC
if (!pJob->constrainedVertices.contains(m1)) {
#endif
J.push_back( J.push_back(
Eigen::Triplet<double>(roffset + si_rod, 3 * m1 + j, jacobianEntry[j])); Eigen::Triplet<double>(roffset + si_rod, 3 * m1 + j, jacobianEntry[j]));
// }
// if (!pJob->constrainedVertices.contains(m2)) { #ifdef EXPLICIT_BC
}
if (!pJob->constrainedVertices.contains(m2)) {
#endif
J.push_back( J.push_back(
Eigen::Triplet<double>(roffset + si_rod, 3 * m2 + j, -jacobianEntry[j])); Eigen::Triplet<double>(roffset + si_rod, 3 * m2 + j, -jacobianEntry[j]));
// } #ifdef EXPLICIT_BC
} }
#endif
}
#ifdef COMPUTE_HESSIAN
if (computeHessian) { if (computeHessian) {
Eigen::Matrix3d Hlen = (1 / len) * Eigen::Matrix<double, 3, 3>::Identity() Eigen::Matrix3d Hlen = (1 / len) * Eigen::Matrix<double, 3, 3>::Identity()
- (1 / (len * len * len)) * (v1 - v2) - (1 / (len * len * len)) * (v1 - v2)
@ -945,6 +960,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
uistiffoffset + 4 * nsegsTotal + dofoffset + si_rod, uistiffoffset + 4 * nsegsTotal + dofoffset + si_rod,
df_dt * (len - restlen))); df_dt * (len - restlen)));
} }
#endif
} }
} }
roffset += rod.numSegments(); roffset += rod.numSegments();
@ -1067,18 +1083,28 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
// const Eigen::Vector3d debug_force1Leimer_xip1 = dEb1_dxip1 * debug_vertr1; // const Eigen::Vector3d debug_force1Leimer_xip1 = dEb1_dxip1 * debug_vertr1;
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
// Gradients for dEb1/dx_(i-1), dEb1/dx_i and dEb1/dx_(i+1) // Gradients for dEb1/dx_(i-1), dEb1/dx_i and dEb1/dx_(i+1)
// if (!pJob->constrainedVertices.contains(m0)) { #ifdef EXPLICIT_BC
J.push_back( if (!pJob->constrainedVertices.contains(m0)) {
Eigen::Triplet<double>(roffset + 2 * idx, 3 * m0 + j, dEb1_dxim1[j])); #endif
// } J.push_back(Eigen::Triplet<double>(roffset + 2 * idx,
// if (!pJob->constrainedVertices.contains(m1)) { 3 * m0 + j,
dEb1_dxim1[j]));
#ifdef EXPLICIT_BC
}
if (!pJob->constrainedVertices.contains(m1)) {
#endif
J.push_back( J.push_back(
Eigen::Triplet<double>(roffset + 2 * idx, 3 * m1 + j, dEb1_dxi[j])); Eigen::Triplet<double>(roffset + 2 * idx, 3 * m1 + j, dEb1_dxi[j]));
// } #ifdef EXPLICIT_BC
// if (!pJob->constrainedVertices.contains(m2)) { }
J.push_back( if (!pJob->constrainedVertices.contains(m2)) {
Eigen::Triplet<double>(roffset + 2 * idx, 3 * m2 + j, dEb1_dxip1[j])); #endif
// } J.push_back(Eigen::Triplet<double>(roffset + 2 * idx,
3 * m2 + j,
dEb1_dxip1[j]));
#ifdef EXPLICIT_BC
}
#endif
} }
// Gradients for dk2/dx_(i-1) and dk2/dx_i // Gradients for dk2/dx_(i-1) and dk2/dx_i
Eigen::Vector3d dk21 = 1.0 / (v1 - v0).norm() Eigen::Vector3d dk21 = 1.0 / (v1 - v0).norm()
@ -1100,20 +1126,29 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
// const Eigen::Vector3d debug_force2Leimer_xip1 = dEb2_dxip1 * debug_vertr2; // const Eigen::Vector3d debug_force2Leimer_xip1 = dEb2_dxip1 * debug_vertr2;
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
// Gradients for dEb2/dx_(i-1), dEb2/dx_i and dEb2/dx_(i+1) // Gradients for dEb2/dx_(i-1), dEb2/dx_i and dEb2/dx_(i+1)
// if (!pJob->constrainedVertices.contains(m0)) { #ifdef EXPLICIT_BC
if (!pJob->constrainedVertices.contains(m0)) {
#endif
J.push_back(Eigen::Triplet<double>(roffset + 2 * idx + 1, J.push_back(Eigen::Triplet<double>(roffset + 2 * idx + 1,
3 * m0 + j, 3 * m0 + j,
dEb2_dxim1[j])); dEb2_dxim1[j]));
// } #ifdef EXPLICIT_BC
// if (!pJob->constrainedVertices.contains(m1)) { }
J.push_back( if (!pJob->constrainedVertices.contains(m1)) {
Eigen::Triplet<double>(roffset + 2 * idx + 1, 3 * m1 + j, dEb2_dxi[j])); #endif
// } J.push_back(Eigen::Triplet<double>(roffset + 2 * idx + 1,
// if (!pJob->constrainedVertices.contains(m2)) { 3 * m1 + j,
dEb2_dxi[j]));
#ifdef EXPLICIT_BC
}
if (!pJob->constrainedVertices.contains(m2)) {
#endif
J.push_back(Eigen::Triplet<double>(roffset + 2 * idx + 1, J.push_back(Eigen::Triplet<double>(roffset + 2 * idx + 1,
3 * m2 + j, 3 * m2 + j,
dEb2_dxip1[j])); dEb2_dxip1[j]));
// } #ifdef EXPLICIT_BC
}
#endif
} }
// Material curvature gradients dd/dtheta1 and dd/theta2 // Material curvature gradients dd/dtheta1 and dd/theta2
@ -1146,6 +1181,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
0.5 * sqrt(factor2 /* * width * width * width*/) 0.5 * sqrt(factor2 /* * width * width * width*/)
* Dd12.dot(kb))); * Dd12.dot(kb)));
#ifdef COMPUTE_HESSIAN
if (computeHessian) { if (computeHessian) {
double chi = 1 + t01.dot(t12); double chi = 1 + t01.dot(t12);
double len01 = (v1 - v0).norm(); double len01 = (v1 - v0).norm();
@ -2014,6 +2050,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
int stop = 0; int stop = 0;
} }
} }
#endif
} }
} else { } else {
r[roffset + 2 * idx] = 0; r[roffset + 2 * idx] = 0;
@ -2083,19 +2120,27 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
const Eigen::Vector3d debug_leimerTwistForce_pos2 = jacob_theta2 const Eigen::Vector3d debug_leimerTwistForce_pos2 = jacob_theta2
* r[roffset + idx]; * r[roffset + idx];
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
// if (!pJob->constrainedVertices.contains(m0)) { #ifdef EXPLICIT_BC
if (!pJob->constrainedVertices.contains(m0)) {
#endif
J.push_back( J.push_back(
Eigen::Triplet<double>(roffset + idx, 3 * m0 + j, -jacob_theta1[j])); Eigen::Triplet<double>(roffset + idx, 3 * m0 + j, -jacob_theta1[j]));
// } #ifdef EXPLICIT_BC
// if (!pJob->constrainedVertices.contains(m1)) { }
if (!pJob->constrainedVertices.contains(m1)) {
#endif
J.push_back(Eigen::Triplet<double>(roffset + idx, J.push_back(Eigen::Triplet<double>(roffset + idx,
3 * m1 + j, 3 * m1 + j,
jacob_theta1[j] - jacob_theta2[j])); jacob_theta1[j] - jacob_theta2[j]));
// } #ifdef EXPLICIT_BC
// if (!pJob->constrainedVertices.contains(m2)) { }
if (!pJob->constrainedVertices.contains(m2)) {
#endif
J.push_back( J.push_back(
Eigen::Triplet<double>(roffset + idx, 3 * m2 + j, jacob_theta2[j])); Eigen::Triplet<double>(roffset + idx, 3 * m2 + j, jacob_theta2[j]));
// } #ifdef EXPLICIT_BC
}
#endif
} }
// Gradients dEt/dtheta1 and dEt/dtheta2 // Gradients dEt/dtheta1 and dEt/dtheta2
const double debug_leimerTwistForce_theta1 = sqrt(debug_factor) const double debug_leimerTwistForce_theta1 = sqrt(debug_factor)
@ -2111,6 +2156,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
dofoffset + thetaoffset + si_rod, dofoffset + thetaoffset + si_rod,
sqrt(debug_factor))); sqrt(debug_factor)));
#ifdef COMPUTE_HESSIAN
if (computeHessian) { if (computeHessian) {
double chi = 1 + t01.dot(t12); double chi = 1 + t01.dot(t12);
double len01 = (v1 - v0).norm(); double len01 = (v1 - v0).norm();
@ -2374,6 +2420,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
int stop = 0; int stop = 0;
} }
} }
#endif
} }
} else } else
r[roffset + idx] = 0; r[roffset + idx] = 0;
@ -2384,6 +2431,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
dofoffset += rod.numSegments(); dofoffset += rod.numSegments();
} }
#ifndef EXPLICIT_BC
// mesh sliding energy Eslide // mesh sliding energy Eslide
// allows ribbons to slide tangentially on mesh surface they try to approximate // allows ribbons to slide tangentially on mesh surface they try to approximate
// see paper Section 7.1 // see paper Section 7.1
@ -2566,6 +2614,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
} }
} }
#ifdef COMPUTE_HESSIAN
if (computeHessian) { if (computeHessian) {
// design variables - Ui anchor positions // design variables - Ui anchor positions
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
@ -2637,6 +2686,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
int stop = 0; int stop = 0;
} }
} }
#endif
} }
// direction constraint for anchor // direction constraint for anchor
@ -2678,6 +2728,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
rod1offset + a.seg, rod1offset + a.seg,
sqrt(factor) * dtheta1.dot(d1dtheta))); sqrt(factor) * dtheta1.dot(d1dtheta)));
#ifdef COMPUTE_HESSIAN
if (computeHessian) { if (computeHessian) {
double len = (vSeg1 - vSeg0).norm(); double len = (vSeg1 - vSeg0).norm();
Eigen::Matrix3d dt_de1 = ((1 / len) * Eigen::Matrix<double, 3, 3>::Identity() Eigen::Matrix3d dt_de1 = ((1 / len) * Eigen::Matrix<double, 3, 3>::Identity()
@ -2971,6 +3022,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
} }
int stop = 0; int stop = 0;
} }
#endif
} }
idx += 4; idx += 4;
@ -2978,6 +3030,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
roffset += idx; roffset += idx;
} }
#endif
// compute energy terms for rod intersections // compute energy terms for rod intersections
int incCount = 0; int incCount = 0;
@ -3119,16 +3172,22 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
* (-k1 * ttilde + st01.cross(d2tilde)); * (-k1 * ttilde + st01.cross(d2tilde));
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
// Gradients for dEb1/dx_(i-1), dEb1/dx_i and dEb1/dx_(i+1) // Gradients for dEb1/dx_(i-1), dEb1/dx_i and dEb1/dx_(i+1)
// if (!pJob->constrainedVertices.contains(m0)) { #ifdef EXPLICIT_BC
if (!pJob->constrainedVertices.contains(m0)) {
#endif
J.push_back(Eigen::Triplet<double>(roffset + incCount, J.push_back(Eigen::Triplet<double>(roffset + incCount,
m0 * 3 + k, m0 * 3 + k,
-sqrt(factor1) * dk11[k])); -sqrt(factor1) * dk11[k]));
// } #ifdef EXPLICIT_BC
// if (!pJob->constrainedVertices.contains(m1)) { }
if (!pJob->constrainedVertices.contains(m1)) {
#endif
J.push_back(Eigen::Triplet<double>(roffset + incCount, J.push_back(Eigen::Triplet<double>(roffset + incCount,
m1 * 3 + k, m1 * 3 + k,
sqrt(factor1) * dk11[k])); sqrt(factor1) * dk11[k]));
// } #ifdef EXPLICIT_BC
}
#endif
} }
J.push_back(Eigen::Triplet<double>(roffset + incCount, J.push_back(Eigen::Triplet<double>(roffset + incCount,
euleroffset + i * 3 + 0, euleroffset + i * 3 + 0,
@ -3145,16 +3204,22 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
* (-k2 * ttilde + st01.cross(d1tilde)); * (-k2 * ttilde + st01.cross(d1tilde));
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
// Gradients for dEb2/dx_(i-1), dEb2/dx_i and dEb2/dx_(i+1) // Gradients for dEb2/dx_(i-1), dEb2/dx_i and dEb2/dx_(i+1)
// if (!pJob->constrainedVertices.contains(m0)) { #ifdef EXPLICIT_BC
if (!pJob->constrainedVertices.contains(m0)) {
#endif
J.push_back(Eigen::Triplet<double>(roffset + incCount + 1, J.push_back(Eigen::Triplet<double>(roffset + incCount + 1,
m0 * 3 + k, m0 * 3 + k,
-sqrt(factor2) * dk21[k])); -sqrt(factor2) * dk21[k]));
// } #ifdef EXPLICIT_BC
// if (!pJob->constrainedVertices.contains(m1)) { }
if (!pJob->constrainedVertices.contains(m1)) {
#endif
J.push_back(Eigen::Triplet<double>(roffset + incCount + 1, J.push_back(Eigen::Triplet<double>(roffset + incCount + 1,
m1 * 3 + k, m1 * 3 + k,
sqrt(factor2) * dk21[k])); sqrt(factor2) * dk21[k]));
// } #ifdef EXPLICIT_BC
}
#endif
} }
J.push_back(Eigen::Triplet<double>(roffset + incCount + 1, J.push_back(Eigen::Triplet<double>(roffset + incCount + 1,
euleroffset + i * 3 + 0, euleroffset + i * 3 + 0,
@ -3183,16 +3248,22 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
Eigen::Vector3d dpsi_dx = 0.5 * kb / (cv1 - cv0).norm(); Eigen::Vector3d dpsi_dx = 0.5 * kb / (cv1 - cv0).norm();
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
// Gradients dEt/dx_(i-1), dEt/dx_i and dEt/dx_(i+1) // Gradients dEt/dx_(i-1), dEt/dx_i and dEt/dx_(i+1)
// if (!pJob->constrainedVertices.contains(m0)) { #ifdef EXPLICIT_BC
if (!pJob->constrainedVertices.contains(m0)) {
#endif
J.push_back(Eigen::Triplet<double>(roffset + incCount + 2, J.push_back(Eigen::Triplet<double>(roffset + incCount + 2,
m0 * 3 + k, m0 * 3 + k,
-sqrt(factor3) * dpsi_dx[k])); -sqrt(factor3) * dpsi_dx[k]));
// } #ifdef EXPLICIT_BC
// if (!pJob->constrainedVertices.contains(m1)) { }
if (!pJob->constrainedVertices.contains(m1)) {
#endif
J.push_back(Eigen::Triplet<double>(roffset + incCount + 2, J.push_back(Eigen::Triplet<double>(roffset + incCount + 2,
m1 * 3 + k, m1 * 3 + k,
sqrt(factor3) * dpsi_dx[k])); sqrt(factor3) * dpsi_dx[k]));
// } #ifdef EXPLICIT_BC
}
#endif
} }
// Gradients dEt/dtheta1 and dEt/dtheta2 // Gradients dEt/dtheta1 and dEt/dtheta2
J.push_back(Eigen::Triplet<double>(roffset + incCount + 2, J.push_back(Eigen::Triplet<double>(roffset + incCount + 2,
@ -3283,6 +3354,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
} }
} }
#ifdef COMPUTE_HESSIAN
if (computeHessian) { if (computeHessian) {
double chi = 1 + ct01.dot(st01); double chi = 1 + ct01.dot(st01);
double len01 = (cv1 - cv0).norm(); double len01 = (cv1 - cv0).norm();
@ -4078,6 +4150,7 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
H_value->push_back(-sqrt(factor3*width) * dpsi22); H_value->push_back(-sqrt(factor3*width) * dpsi22);
*/ */
} }
#endif
} }
incCount += 3; incCount += 3;
} }
@ -4089,12 +4162,31 @@ void DER_leimer::rAndJGrid(const RodConfig &config,
exit(-1); exit(-1);
if (Jr) { if (Jr) {
// std::vector<Eigen::Triplet<double>> J_nonConstrained;
// std::unordered_set<int> constrainedDof_global;
// for (const auto &constrainedViDof : pJob->constrainedVertices) {
// const int vi = constrainedViDof.first;
// std::unordered_set<int> &constrainedDof_local = constrainedViDof.second;
// }
// for (auto &triplet : J) {
// }
Jr->setFromTriplets(J.begin(), J.end()); Jr->setFromTriplets(J.begin(), J.end());
} }
#ifdef COMPUTE_HESSIAN
if (computeHessian) { if (computeHessian) {
Ju->resize(nterms, udofs); Ju->resize(nterms, udofs);
Ju->setFromTriplets(Jui.begin(), Jui.end()); Ju->setFromTriplets(Jui.begin(), Jui.end());
} }
#endif
}
Eigen::Vector3d DER_leimer::getPerpendicularVector(const Eigen::Vector3d &t) const
{
Eigen::Vector3d candidate1 = Eigen::Vector3d(1, 0, 0).cross(t),
candidate2 = Eigen::Vector3d(0, 1, 0).cross(t);
return (candidate1.norm() > candidate2.norm()) ? candidate1.normalized()
: candidate2.normalized();
} }
DER_leimer::RodConfig *DER_leimer::readRodGrid( DER_leimer::RodConfig *DER_leimer::readRodGrid(
@ -4203,29 +4295,8 @@ DER_leimer::RodConfig *DER_leimer::readRodGrid(
const Eigen::Vector3d v1 = rodState.centerlinePositions.row( const Eigen::Vector3d v1 = rodState.centerlinePositions.row(
(si_rod + 1) % numVertices_rod); //the % numVertices_rod is not needed (si_rod + 1) % numVertices_rod); //the % numVertices_rod is not needed
const Eigen::Vector3d e = (v1 - v0).normalized(); const Eigen::Vector3d e = (v1 - v0).normalized();
Eigen::Vector3d segmentDirector = Eigen::Vector3d(0, 0, 1); // rodState.directors.row(si_rod) = getPerpendicularVector(e);
/*= ((pMesh->edge[rodIndex].cV(0)->cN() + pMesh->edge[rodIndex].cV(1)->cN()) / 2) rodState.directors.row(si_rod) = Eigen::Vector3d(0, 0, 1);
.ToEigenVector<Eigen::Vector3d>()
.normalized();*/
// = (e.cross(Eigen::Vector3d(0, 0, 1).normalized())).normalized();
// switch (rodIndex) {
// case 0:
// segmentDirector = Eigen::Vector3d(1, 0, 0);
// break;
// case 1:
// segmentDirector = Eigen::Vector3d(0, -1, 0);
// break;
// case 2:
// segmentDirector = Eigen::Vector3d(-1, 0, 0);
// segmentDirector = Eigen::Vector3d(-1, 0, 0);
// break;
// default:
// assert(false);
// }
rodState.directors.row(si_rod) = segmentDirector;
// rodState.directors.row(si_rod) = binorms[si_rod]; // rodState.directors.row(si_rod) = binorms[si_rod];
// for (int k = 0; k < 3; k++) { // for (int k = 0; k < 3; k++) {
@ -4745,3 +4816,10 @@ int DER_leimer::RodConfig::getNumDoF() const
ndofs += 3 * numIntersections(); // euler angles as DOFs for intersections ndofs += 3 * numIntersections(); // euler angles as DOFs for intersections
return ndofs; return ndofs;
} }
void DER_leimer::setStructure(const std::shared_ptr<SimulationMesh> &pMesh)
{
std::cout << "This function is currently not implemented" << std::endl;
assert(false);
std::terminate();
}

View File

@ -139,6 +139,8 @@ public:
int getNumDoF() const; int getNumDoF() const;
}; };
void setStructure(const std::shared_ptr<SimulationMesh> &pMesh) override;
private: private:
bool simulateOneStepGrid(RodConfig *config); bool simulateOneStepGrid(RodConfig *config);
@ -181,6 +183,7 @@ private:
SimulationResults constructSimulationResults(const std::shared_ptr<SimulationJob> &pJob, SimulationResults constructSimulationResults(const std::shared_ptr<SimulationJob> &pJob,
RodConfig *config) const; RodConfig *config) const;
std::shared_ptr<SimulationJob> pJob; std::shared_ptr<SimulationJob> pJob;
Eigen::Vector3d getPerpendicularVector(const Eigen::Vector3d &t) const;
}; };
Eigen::Matrix3d eulerRotation(double e0, double e1, double e2, int deriv = -1, int deriv2 = -1); Eigen::Matrix3d eulerRotation(double e0, double e1, double e2, int deriv = -1, int deriv2 = -1);