void RecomputeRadialReturn::computeStress(RankTwoTensor & strain_increment, RankTwoTensor & inelastic_strain_increment, RankTwoTensor & stress_new) { // Given the stretching, update the inelastic strain // Compute the stress in the intermediate configuration while retaining the stress history // compute the deviatoric trial stress and trial strain from the current intermediate configuration RankTwoTensor deviatoric_trial_stress = stress_new.deviatoric(); // compute the effective trial stress Real dev_trial_stress_squared = deviatoric_trial_stress.doubleContraction(deviatoric_trial_stress); Real effective_trial_stress = std::sqrt(3.0 / 2.0 * dev_trial_stress_squared); //If the effective trial stress is zero, so should the inelastic strain increment be zero //In that case skip the entire iteration if the effective trial stress is zero if (effective_trial_stress != 0.0) { computeStressInitialize(effective_trial_stress); // Use Newton sub-iteration to determine the scalar effective inelastic strain increment Real scalar_effective_inelastic_strain = 0; unsigned int iteration = 0; Real residual = 10; // use a large number here to guarantee at least one loop through while Real norm_residual = 10; Real first_norm_residual = 10; // create an output string with iteration information when errors occur std::string iteration_output; while (iteration < _max_its && norm_residual > _absolute_tolerance && (norm_residual/first_norm_residual) > _relative_tolerance) { iterationInitialize(scalar_effective_inelastic_strain); residual = computeResidual(effective_trial_stress, scalar_effective_inelastic_strain); norm_residual = std::abs(residual); if (iteration == 0) { first_norm_residual = norm_residual; if (first_norm_residual == 0) first_norm_residual = 1; } Real derivative = computeDerivative(effective_trial_stress, scalar_effective_inelastic_strain); scalar_effective_inelastic_strain -= residual / derivative; if (_output_iteration_info || _output_iteration_info_on_error) { iteration_output = "In the element " + Moose::stringify(_current_elem->id()) + + " and the qp point " + Moose::stringify(_qp) + ": \n" + + " iteration = " + Moose::stringify(iteration ) + "\n" + + " effective trial stress = " + Moose::stringify(effective_trial_stress) + "\n" + + " scalar effective inelastic strain = " + Moose::stringify(scalar_effective_inelastic_strain) +"\n" + + " relative residual = " + Moose::stringify(norm_residual/first_norm_residual) + "\n" + + " relative tolerance = " + Moose::stringify(_relative_tolerance) + "\n" + + " absolute residual = " + Moose::stringify(norm_residual) + "\n" + + " absolute tolerance = " + Moose::stringify(_absolute_tolerance) + "\n"; } iterationFinalize(scalar_effective_inelastic_strain); ++iteration; } if (_output_iteration_info) _console << iteration_output << std::endl; if (iteration == _max_its && norm_residual > _absolute_tolerance && (norm_residual/first_norm_residual) > _relative_tolerance) { if (_output_iteration_info_on_error) Moose::err << iteration_output; mooseError("Exceeded maximum iterations in RecomputeRadialReturn solve for material: " << _name << ". Rerun with 'output_iteration_info_on_error = true' for more information."); } // compute inelastic strain increments while avoiding a potential divide by zero inelastic_strain_increment = deviatoric_trial_stress; inelastic_strain_increment *= (3.0 / 2.0 * scalar_effective_inelastic_strain / effective_trial_stress); } else inelastic_strain_increment.zero(); strain_increment -= inelastic_strain_increment; stress_new = _elasticity_tensor[_qp] * (strain_increment + _elastic_strain_old[_qp]); computeStressFinalize(inelastic_strain_increment); }
void ReturnMappingModel::computeStress( const Elem & /*current_elem*/, unsigned qp, const SymmElasticityTensor & elasticityTensor, const SymmTensor & stress_old, SymmTensor & strain_increment, SymmTensor & stress_new, SymmTensor & inelastic_strain_increment ) { // compute deviatoric trial stress SymmTensor dev_trial_stress(stress_new); dev_trial_stress.addDiag( -dev_trial_stress.trace()/3.0 ); // compute effective trial stress Real dts_squared = dev_trial_stress.doubleContraction(dev_trial_stress); Real effective_trial_stress = std::sqrt(1.5 * dts_squared); // compute effective strain increment SymmTensor dev_strain_increment(strain_increment); dev_strain_increment.addDiag( -strain_increment.trace()/3.0); _effective_strain_increment = dev_strain_increment.doubleContraction(dev_strain_increment); _effective_strain_increment = std::sqrt(2.0/3.0 * _effective_strain_increment); computeStressInitialize(qp, effective_trial_stress, elasticityTensor); // Use Newton sub-iteration to determine inelastic strain increment Real scalar = 0; unsigned int it = 0; Real residual = 10; Real norm_residual = 10; Real first_norm_residual = 10; std::stringstream iter_output; while (it < _max_its && norm_residual > _absolute_tolerance && (norm_residual/first_norm_residual) > _relative_tolerance) { iterationInitialize( qp, scalar ); residual = computeResidual(qp, effective_trial_stress, scalar); norm_residual = std::abs(residual); if (it == 0) { first_norm_residual = norm_residual; if (first_norm_residual == 0) { first_norm_residual = 1; } } scalar -= residual / computeDerivative(qp, effective_trial_stress, scalar); if (_output_iteration_info == true || _output_iteration_info_on_error == true) { iter_output << " it=" << it << " trl_strs=" << effective_trial_stress << " scalar=" << scalar << " rel_res=" << norm_residual/first_norm_residual << " rel_tol=" << _relative_tolerance << " abs_res=" << norm_residual << " abs_tol=" << _absolute_tolerance << std::endl; } iterationFinalize( qp, scalar ); ++it; } if (_output_iteration_info) _console << iter_output.str(); if (it == _max_its && norm_residual > _absolute_tolerance && (norm_residual/first_norm_residual) > _relative_tolerance) { if (_output_iteration_info_on_error) { Moose::err << iter_output.str(); } mooseError("Max sub-newton iteration hit during nonlinear constitutive model solve! (" << _name << ")"); } // compute inelastic and elastic strain increments (avoid potential divide by zero - how should this be done)? if (effective_trial_stress < 0.01) { effective_trial_stress = 0.01; } inelastic_strain_increment = dev_trial_stress; inelastic_strain_increment *= (1.5*scalar/effective_trial_stress); strain_increment -= inelastic_strain_increment; // compute stress increment stress_new = elasticityTensor * strain_increment; // update stress stress_new += stress_old; computeStressFinalize(qp, inelastic_strain_increment); }
void ReturnMappingModel::computeStress(const Elem & /*current_elem*/, unsigned qp, const SymmElasticityTensor & elasticityTensor, const SymmTensor & stress_old, SymmTensor & strain_increment, SymmTensor & stress_new, SymmTensor & inelastic_strain_increment) { // compute deviatoric trial stress SymmTensor dev_trial_stress(stress_new); dev_trial_stress.addDiag(-dev_trial_stress.trace()/3.0); // compute effective trial stress Real dts_squared = dev_trial_stress.doubleContraction(dev_trial_stress); Real effective_trial_stress = std::sqrt(1.5 * dts_squared); // compute effective strain increment SymmTensor dev_strain_increment(strain_increment); dev_strain_increment.addDiag(-strain_increment.trace()/3.0); _effective_strain_increment = dev_strain_increment.doubleContraction(dev_strain_increment); _effective_strain_increment = std::sqrt(2.0/3.0 * _effective_strain_increment); computeStressInitialize(qp, effective_trial_stress, elasticityTensor); // Use Newton sub-iteration to determine inelastic strain increment Real scalar = 0; unsigned int it = 0; Real residual = 10; Real norm_residual = 10; Real first_norm_residual = 10; std::string iter_output; while (it < _max_its && norm_residual > _absolute_tolerance && (norm_residual/first_norm_residual) > _relative_tolerance) { iterationInitialize(qp, scalar); residual = computeResidual(qp, effective_trial_stress, scalar); norm_residual = std::abs(residual); if (it == 0) { first_norm_residual = norm_residual; if (first_norm_residual == 0) { first_norm_residual = 1; } } scalar -= residual / computeDerivative(qp, effective_trial_stress, scalar); if (_output_iteration_info == true || _output_iteration_info_on_error == true) { iter_output = "In the element " + Moose::stringify(_current_elem->id()) + + " and the qp point " + Moose::stringify(qp) + ": \n" + + " iteration = " + Moose::stringify(it ) + "\n" + + " effective trial stress = " + Moose::stringify(effective_trial_stress) + "\n" + + " scalar effective inelastic strain = " + Moose::stringify(scalar) +"\n" + + " relative residual = " + Moose::stringify(norm_residual/first_norm_residual) + "\n" + + " relative tolerance = " + Moose::stringify(_relative_tolerance) + "\n" + + " absolute residual = " + Moose::stringify(norm_residual) + "\n" + + " absolute tolerance = " + Moose::stringify(_absolute_tolerance) + "\n"; } iterationFinalize(qp, scalar); ++it; } if (_output_iteration_info) _console << iter_output; if (it == _max_its && norm_residual > _absolute_tolerance && (norm_residual/first_norm_residual) > _relative_tolerance) { if (_output_iteration_info_on_error) { Moose::err << iter_output; } mooseError("Exceeded maximum iterations in ReturnMappingModel solve for material: " << _name << ". Rerun with 'output_iteration_info_on_error = true' for more information."); } // compute inelastic and elastic strain increments (avoid potential divide by zero - how should this be done)? if (effective_trial_stress < 0.01) { effective_trial_stress = 0.01; } inelastic_strain_increment = dev_trial_stress; inelastic_strain_increment *= (1.5*scalar/effective_trial_stress); strain_increment -= inelastic_strain_increment; // compute stress increment stress_new = elasticityTensor * strain_increment; // update stress stress_new += stress_old; computeStressFinalize(qp, inelastic_strain_increment); }
int main() { initialize(); double minDistance = DBL_MAX; // The very largest allowed value for double type. for (int i = 0; i < iteration; ++i) { iterationInitialize(); printf("Iterating %d ...\n", i + 1); for (int j = 0; j < nrOfAnts; ++j) { for (int iIndex = 0; iIndex < nrOfCities; ++iIndex) { routeIndex[iIndex].cumP = 0; routeIndex[iIndex].visited = 0; } int temp = rand() % nrOfCities; // Randomly choose a city as the very starting point for the ant j. route[j][0] = temp; routeIndex[temp].visited = 1; // Determine the next city given the current city, and a complete route covering all cities is built for the ant j afterwards. for (int k = 1; k < nrOfCities - 1; ++k) { route[j][k] = transit(routeIndex, route[j][k - 1]); } // Set the only unvisited city as the last city. for (int iIndex = 0; iIndex < nrOfCities; ++iIndex) { if (!routeIndex[iIndex].visited) { route[j][nrOfCities - 1] = iIndex; } } distance[j] = getDistance(route[j], nrOfCities); } // The following 2 double-loop update the pheromone matrix. for (int j = 0; j < nrOfAnts; ++j) { for (int k = 0; k < nrOfCities - 1; ++k) { deltaTau[route[j][k]][route[j][k + 1]] = Q / distance[j]; } } for (int j = 0; j < nrOfCities; ++j) { for (int k = 0; k < nrOfCities; ++k) { tau[j][k] += (1 - rho) * tau[j][k] + deltaTau[j][k]; } } int minIdx = minIndex(distance, nrOfAnts); int minRoute[nrOfCities]; if (distance[minIdx] < minDistance) { minDistance = distance[minIdx]; copyArrayElement(route[minIdx], minRoute, nrOfCities); } printf("The minimum distance: %lf\n", minDistance); printf("Corresponding route:\n"); for (int i = 0; i < nrOfCities - 1; ++i) { printf("%d->", route[minIdx][i]+1); } printf("%d\n", route[minIdx][nrOfCities - 1]+1); } return 0; }