@@ -157,13 +157,13 @@ function init_time_solver!(nr::NewtonRaphson, dh::ThreadsBodyDataHandler)
157157 end
158158
159159 # Material limitations
160- working_mats = (:BBMaterial , :OSBMaterial , :CKIMaterial , :DHBBMaterial , :CMaterial )
161- if nameof (typeof (chunk. mat)) ∉ working_mats
162- msg = " NewtonRaphson solver may not work correctly "
163- msg *= " with $( nameof ( typeof (chunk . mat))) ! \n "
164- msg *= " Be careful and check results carefully! "
165- print_log ( stdout , " \n " )
166- @warn msg
160+ incompatible_mats = (:CRMaterial , :RKCRMaterial )
161+ if nameof (typeof (chunk. mat)) ∈ incompatible_mats
162+ msg = " $( nameof ( typeof (chunk . mat))) not compatible with Newton-Raphson! \n "
163+ msg *= " The material uses stress rotation designed for dynamic simulations. \n "
164+ msg *= " For quasi-static Newton-Raphson simulations, consider using the material "
165+ msg *= " without stress rotation instead. \n "
166+ throw ( ArgumentError ( msg))
167167 end
168168
169169 # No damage allowed in whole model
@@ -199,12 +199,13 @@ function init_time_solver!(::NewtonRaphson, ::AbstractDataHandler)
199199end
200200
201201function minimum_volume (dh:: ThreadsBodyDataHandler )
202- min_vols = fill (Inf , dh. n_chunks)
203- @threads :static for chunk_id in eachindex (dh. chunks)
204- chunk = dh. chunks[chunk_id]
205- min_vols[chunk_id] = minimum (chunk. system. volume)
206- end
207- return minimum (min_vols)
202+ # min_vols = fill(Inf, dh.n_chunks)
203+ # @threads :static for chunk_id in eachindex(dh.chunks)
204+ # chunk = dh.chunks[chunk_id]
205+ # min_vols[chunk_id] = minimum(chunk.system.volume)
206+ # end
207+ # return minimum(min_vols)
208+ return minimum (dh. chunks[1 ]. system. volume)
208209end
209210
210211# TODO : Add MPI version later
@@ -406,7 +407,9 @@ function calc_jacobian!(chunk::AbstractBodyChunk, nr::NewtonRaphson, t, Δt)
406407 # Final restore: recalculate forces at original state
407408 b_int .= b_int_copy
408409
409- # Apply penalty method for constrained DOFs - set rows and columns to zero
410+ # Apply constraint elimination for constrained DOFs
411+ # Since residual is already zero for these DOFs and we only update free DOFs,
412+ # we set the row/column to identity to make the system well-conditioned
410413 for dof in constrained_dofs
411414 # Zero out row
412415 for j in axes (jacobian, 2 )
@@ -416,8 +419,8 @@ function calc_jacobian!(chunk::AbstractBodyChunk, nr::NewtonRaphson, t, Δt)
416419 for i in axes (jacobian, 1 )
417420 @inbounds jacobian[i, dof] = 0.0
418421 end
419- # Set diagonal to large penalty value
420- @inbounds jacobian[dof, dof] = 1e12
422+ # Set diagonal to 1 (identity), ensures Δu[dof] = 0 since residual[dof] = 0
423+ @inbounds jacobian[dof, dof] = 1.0
421424 end
422425
423426 return nothing
0 commit comments