void Fem3DElementTetrahedron::initialize(const SurgSim::Math::OdeState& state)
{
	// Test the validity of the physical parameters
	FemElement::initialize(state);

	for (auto nodeId = m_nodeIds.cbegin(); nodeId != m_nodeIds.cend(); nodeId++)
	{
		SURGSIM_ASSERT(*nodeId >= 0 && *nodeId < state.getNumNodes())
				<< "Invalid nodeId " << *nodeId << " expected in range [0.." << state.getNumNodes() - 1 << "]";
	}

	// Store the rest state for this tetrahedron in m_x0
	getSubVector(state.getPositions(), m_nodeIds, 3, &m_x0);

	// Verify the Counter clock-wise condition
	auto A = getSubVector(m_x0, 0, 3);
	auto B = getSubVector(m_x0, 1, 3);
	auto C = getSubVector(m_x0, 2, 3);
	auto D = getSubVector(m_x0, 3, 3);
	SurgSim::Math::Vector3d AB = B - A;
	SurgSim::Math::Vector3d AC = C - A;
	SurgSim::Math::Vector3d AD = D - A;
	SURGSIM_LOG_IF(AB.cross(AC).dot(AD) < 0, SurgSim::Framework::Logger::getDefaultLogger(), WARNING)
			<< "Tetrahedron ill-defined (ABC defined counter clock viewed from D) with node ids[" <<
			m_nodeIds[0] << ", " << m_nodeIds[1] << ", " << m_nodeIds[2] << ", " << m_nodeIds[3] << "]";

	// Pre-compute the mass and stiffness matrix
	computeMass(state, &m_M);
	computeStiffness(state, &m_K);
}
Пример #2
0
void Fem3DElementCube::initialize(const SurgSim::Math::OdeState& state)
{
	// Test the validity of the physical parameters
	FemElement::initialize(state);

	// Set the shape functions coefficients
	// Ni(epsilon, eta, mu) = (1 + epsilon * sign(epsilon_i))(1 + eta * sign(eta_i))(1 + mu * sign(mu_i))/8
	std::array<double, 8> tmpEpsilon = {{ -1.0, +1.0, +1.0, -1.0, -1.0, +1.0, +1.0, -1.0}};
	std::array<double, 8> tmpEta     = {{ -1.0, -1.0, +1.0, +1.0, -1.0, -1.0, +1.0, +1.0}};
	std::array<double, 8> tmpMu      = {{ -1.0, -1.0, -1.0, -1.0, +1.0, +1.0, +1.0, +1.0}};
	m_shapeFunctionsEpsilonSign = tmpEpsilon;
	m_shapeFunctionsEtaSign     = tmpEta;
	m_shapeFunctionsMuSign      = tmpMu;

	// Store the 8 nodeIds in order
	for (auto nodeId = m_nodeIds.cbegin(); nodeId != m_nodeIds.cend(); ++nodeId)
	{
		SURGSIM_ASSERT(*nodeId >= 0 && *nodeId < state.getNumNodes()) <<
						"Invalid nodeId " << *nodeId << " expected in range [0.." << state.getNumNodes() - 1 << "]";
	}

	// Store the rest state for this cube in m_elementRestPosition
	getSubVector(state.getPositions(), m_nodeIds, 3, &m_elementRestPosition);

	// Compute the cube rest volume
	m_restVolume = getVolume(state);

	// Pre-compute the mass and stiffness matrix
	computeMass(state, &m_M);
	computeStiffness(state, &m_strain, &m_stress, &m_K);
}