コード例 #1
0
void Multigrid::smooth()
{
    double a1, a2, a3, a4;
    double b1, b2, b3, b4;
    double a, b;
    for (int i = 1; i <= Nx; i++)
        for (int j = 1; j <= Ny; j++)
        {
            a1 = ddx_east_p(i, j);
            a2 = ddx_west_p(i, j);
            a3 = ddy_north_p(i, j);
            a4 = ddy_south_p(i, j);
            b1 = ddx_east_r(i, j);
            b2 = ddx_west_r(i, j);
            b3 = ddy_north_r(i, j);
            b4 = ddy_south_r(i, j);
            a = (a1 - a2)/dx + (a3 - a4)/dy + isSolid[i][j];
            b = (b1 - b2)/dx + (b3 - b4)/dy;
            u[i][j] = (R[i][j]/a - b/a)*(1.0 - isSolid[i][j]);
        }
    
    computeResidual();
    n++;
    return;
}
コード例 #2
0
// This is a recursive function which calls itselfs and sub routines of MultiGridSolver 
void MultiGridSolver::mgmSolve(const size_t& level)
{
        //std::cout << " Level : " << level << " mgmSolve() \n ";  
        assert(level >0 && level <= numLevel_) ;    
       
       // if(level!=1)
       // {       
                applyPreSmoothing(level);         // Before going to coaser level lets smoothen the solution by applying RBGS Guass Seidel neu1_ times  
              
                computeResidual(level);          // Before going to the coaser level, let us compute the error at the current level
                 
                if(level!=1)                    // We can get any further coarse if level is one
                applyRestriction(level);        // Restrict the error term and assign it to f_
       // }                                     // Its time to go to the coaser level :)
                                           
        if(level == 1)
                                                  // This is the end of recursion, Compute Solution
                {      
                        //std::cout << "Exact solution\n";
                        applyRBGS_Iter(level);    // Apply Red Black Guass Seidel to compute the exact solution at coarsest level
                }
        else
        {
                mgmSolve(level-1);                // If we have not reached at the coarsest level keep going down
                
                applyInterpolation(level-1);      // Lets see how much we have improved the error by going to the Coaser level, Lets come back to finer level and add the effect;     
        }
        
       // if(level!=1)
        applyPostSmoothing(level);                // Lets smotthen the solution a bit
        
}
コード例 #3
0
int main(int argc, char** argv)
{
    // Get user parameters.
    Opm::parameter::ParameterGroup param(argc, argv, false);

    // Create the Equelle runtime.
    EquelleRuntimeCPU er(param);

    ensureRequirements(er);

    // ============= Generated code starts here ================

    const Scalar k = er.inputScalarWithDefault("k", double(0.3));
    const CollOfScalar u_initial = er.inputCollectionOfScalar("u_initial", er.allCells());
    const CollOfFace dirichlet_boundary = er.inputDomainSubsetOf("dirichlet_boundary", er.boundaryFaces());
    const CollOfScalar dirichlet_val = er.inputCollectionOfScalar("dirichlet_val", dirichlet_boundary);
    const CollOfScalar vol = er.norm(er.allCells());
    const CollOfFace interior_faces = er.interiorFaces();
    const CollOfCell first = er.firstCell(interior_faces);
    const CollOfCell second = er.secondCell(interior_faces);
    const CollOfScalar itrans = (k * (er.norm(interior_faces) / er.norm((er.centroid(first) - er.centroid(second)))));
    const CollOfFace bf = er.boundaryFaces();
    const CollOfCell bf_cells = er.trinaryIf(er.isEmpty(er.firstCell(bf)), er.secondCell(bf), er.firstCell(bf));
    const CollOfScalar bf_sign = er.trinaryIf(er.isEmpty(er.firstCell(bf)), er.operatorExtend(-double(1), bf), er.operatorExtend(double(1), bf));
    const CollOfScalar btrans = (k * (er.norm(bf) / er.norm((er.centroid(bf) - er.centroid(bf_cells)))));
    const CollOfScalar dir_sign = er.operatorOn(bf_sign, er.boundaryFaces(), dirichlet_boundary);
    std::function<CollOfScalar(const CollOfScalar&)> computeInteriorFlux = [&](const CollOfScalar& u) -> CollOfScalar {
        return (-itrans * er.gradient(u));
    };
    std::function<CollOfScalar(const CollOfScalar&)> computeBoundaryFlux = [&](const CollOfScalar& u) -> CollOfScalar {
        const CollOfScalar u_dirbdycells = er.operatorOn(u, er.allCells(), er.operatorOn(bf_cells, er.boundaryFaces(), dirichlet_boundary));
        const CollOfScalar dir_fluxes = ((er.operatorOn(btrans, er.boundaryFaces(), dirichlet_boundary) * dir_sign) * (u_dirbdycells - dirichlet_val));
        return er.operatorExtend(dir_fluxes, dirichlet_boundary, er.boundaryFaces());
    };
    std::function<CollOfScalar(const CollOfScalar&, const CollOfScalar&, const Scalar&)> computeResidual = [&](const CollOfScalar& u, const CollOfScalar& u0, const Scalar& dt) -> CollOfScalar {
        const CollOfScalar ifluxes = computeInteriorFlux(u);
        const CollOfScalar bfluxes = computeBoundaryFlux(u);
        const CollOfScalar fluxes = (er.operatorExtend(ifluxes, er.interiorFaces(), er.allFaces()) + er.operatorExtend(bfluxes, er.boundaryFaces(), er.allFaces()));
        const CollOfScalar residual = ((u - u0) + ((dt / vol) * er.divergence(fluxes)));
        return residual;
    };
    const SeqOfScalar timesteps = er.inputSequenceOfScalar("timesteps");
    CollOfScalar u0;
    u0 = u_initial;
    for (const Scalar& dt : timesteps) {
        std::function<CollOfScalar(const CollOfScalar&)> computeResidualLocal = [&](const CollOfScalar& u) -> CollOfScalar {
            return computeResidual(u, u0, dt);
        };
        const CollOfScalar u_guess = u0;
        const CollOfScalar u = er.newtonSolve(computeResidualLocal, u_guess);
        er.output("u", u);
        er.output("maximum of u", er.maxReduce(u));
        u0 = u;
    }

    // ============= Generated code ends here ================

    return 0;
}
コード例 #4
0
void Multigrid::solve()
{
    smooth();
    computeResidual();
    while (error() > tol() & n < maxIter())
        iterate();
    if (n == maxIter())
        cout << "Multigrid reached maximum number of iterations" << endl;
}
コード例 #5
0
  bool operator()(
    const T* const cam_RtK, // [R;t;K]
    const T* const pos_3dpoint,
    T* out_residuals) const
  {
    computeResidual(
      cam_RtK, // => cam_R
      & cam_RtK[3], // => cam_t
      & cam_RtK[6], // => cam_K
      pos_3dpoint,
      m_pos_2dpoint,
      out_residuals);

    return true;
  }
コード例 #6
0
  bool operator()(
    const T* const cam_K,
    const T* const cam_Rt,
    const T* const pos_3dpoint,
    T* out_residuals) const
  {
    computeResidual(
      cam_Rt, // => cam_R
      & cam_Rt[3], // => cam_t
      cam_K,
      pos_3dpoint,
      m_pos_2dpoint,
      out_residuals );

    return true;
  }
コード例 #7
0
  bool operator()(
    const T* const cam_RtK, // [R;t;K]
    T* out_residuals) const
  {
    T pos_3dpoint[3];
    pos_3dpoint[0] = T(m_pos_3dpoint[0]);
    pos_3dpoint[1] = T(m_pos_3dpoint[1]);
    pos_3dpoint[2] = T(m_pos_3dpoint[2]);

    computeResidual(
      cam_RtK, // => cam_R
      & cam_RtK[3], // => cam_t
      & cam_RtK[6], // => cam_K [f,ppx,ppy]
      pos_3dpoint,
      m_pos_2dpoint,
      out_residuals);

    return true;
  }
コード例 #8
0
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);
}
コード例 #9
0
bool
FrictionalContactProblem::calculateSlip(const NumericVector<Number>& ghosted_solution,
                                        std::vector<SlipData> * iterative_slip)
{
    NonlinearSystem & nonlinear_sys = getNonlinearSystem();
    unsigned int dim = nonlinear_sys.subproblem().mesh().dimension();

    MooseVariable * residual_x_var = &getVariable(0,_residual_x);
    MooseVariable * residual_y_var = &getVariable(0,_residual_y);
    MooseVariable * residual_z_var = NULL;
    MooseVariable * diag_stiff_x_var = &getVariable(0,_diag_stiff_x);
    MooseVariable * diag_stiff_y_var = &getVariable(0,_diag_stiff_y);
    MooseVariable * diag_stiff_z_var = NULL;
    MooseVariable * inc_slip_x_var = &getVariable(0,_inc_slip_x);
    MooseVariable * inc_slip_y_var = &getVariable(0,_inc_slip_y);
    MooseVariable * inc_slip_z_var = NULL;
    if (dim == 3)
    {
        residual_z_var = &getVariable(0,_residual_z);
        diag_stiff_z_var = &getVariable(0,_diag_stiff_z);
        inc_slip_z_var = &getVariable(0,_inc_slip_z);
    }

    bool updatedSolution = false;
    _slip_residual = 0.0;
    _it_slip_norm = 0.0;
    _inc_slip_norm = 0.0;
    TransientNonlinearImplicitSystem & system = getNonlinearSystem().sys();

    if (iterative_slip)
        iterative_slip->clear();

    if (getDisplacedProblem() && _interaction_params.size() > 0)
    {
        computeResidual(system, ghosted_solution, *system.rhs);

        _num_contact_nodes = 0;
        _num_slipping = 0;
        _num_slipped_too_far = 0;

        GeometricSearchData & displaced_geom_search_data = getDisplacedProblem()->geomSearchData();
        std::map<std::pair<unsigned int, unsigned int>, PenetrationLocator *> * penetration_locators = &displaced_geom_search_data._penetration_locators;

        AuxiliarySystem & aux_sys = getAuxiliarySystem();
        const NumericVector<Number> & aux_solution = *aux_sys.currentSolution();

        for (std::map<std::pair<unsigned int, unsigned int>, PenetrationLocator *>::iterator plit = penetration_locators->begin();
                plit != penetration_locators->end();
                ++plit)
        {
            PenetrationLocator & pen_loc = *plit->second;
            std::set<dof_id_type> & has_penetrated = pen_loc._has_penetrated;

            bool frictional_contact_this_interaction = false;

            std::map<std::pair<int,int>,InteractionParams>::iterator ipit;
            std::pair<int,int> ms_pair(pen_loc._master_boundary,pen_loc._slave_boundary);
            ipit = _interaction_params.find(ms_pair);
            if (ipit != _interaction_params.end())
                frictional_contact_this_interaction = true;

            if (frictional_contact_this_interaction)
            {

                InteractionParams & interaction_params = ipit->second;
                Real slip_factor = interaction_params._slip_factor;
                Real slip_too_far_factor = interaction_params._slip_too_far_factor;
                Real friction_coefficient = interaction_params._friction_coefficient;


                std::vector<dof_id_type> & slave_nodes = pen_loc._nearest_node._slave_nodes;

                for (unsigned int i=0; i<slave_nodes.size(); i++)
                {
                    dof_id_type slave_node_num = slave_nodes[i];

                    if (pen_loc._penetration_info[slave_node_num])
                    {
                        PenetrationInfo & info = *pen_loc._penetration_info[slave_node_num];
                        const Node * node = info._node;

                        if (node->processor_id() == processor_id())
                        {

                            std::set<dof_id_type>::iterator hpit = has_penetrated.find(slave_node_num);

                            if (hpit != has_penetrated.end())
                            {
                                _num_contact_nodes++;

                                VectorValue<dof_id_type> residual_dofs(node->dof_number(aux_sys.number(), residual_x_var->number(), 0),
                                                                       node->dof_number(aux_sys.number(), residual_y_var->number(), 0),
                                                                       (residual_z_var ? node->dof_number(aux_sys.number(), residual_z_var->number(), 0) : 0));

                                VectorValue<dof_id_type> diag_stiff_dofs(node->dof_number(aux_sys.number(), diag_stiff_x_var->number(), 0),
                                        node->dof_number(aux_sys.number(), diag_stiff_y_var->number(), 0),
                                        (diag_stiff_z_var ? node->dof_number(aux_sys.number(), diag_stiff_z_var->number(), 0) : 0));

                                VectorValue<dof_id_type> inc_slip_dofs(node->dof_number(aux_sys.number(), inc_slip_x_var->number(), 0),
                                                                       node->dof_number(aux_sys.number(), inc_slip_y_var->number(), 0),
                                                                       (inc_slip_z_var ? node->dof_number(aux_sys.number(), inc_slip_z_var->number(), 0) : 0));

                                RealVectorValue res_vec;
                                RealVectorValue stiff_vec;
                                RealVectorValue slip_inc_vec;

                                for (unsigned int i=0; i<dim; ++i)
                                {
                                    res_vec(i) = aux_solution(residual_dofs(i));
                                    stiff_vec(i) = aux_solution(diag_stiff_dofs(i));
                                    slip_inc_vec(i) = aux_solution(inc_slip_dofs(i));
                                }

                                RealVectorValue slip_iterative(0.0,0.0,0.0);
                                Real interaction_slip_residual = 0.0;
//                _console<<"inc  slip: "<<slip_inc_vec<<std::endl;
//                _console<<"info slip: "<<info._incremental_slip<<std::endl;
//                ContactState state = calculateInteractionSlip(slip_iterative, interaction_slip_residual, info._normal, res_vec, info._incremental_slip, stiff_vec, friction_coefficient, slip_factor, slip_too_far_factor, dim);
                                ContactState state = calculateInteractionSlip(slip_iterative, interaction_slip_residual, info._normal, res_vec, slip_inc_vec, stiff_vec, friction_coefficient, slip_factor, slip_too_far_factor, dim);
//                _console<<"iter slip: "<<slip_iterative<<std::endl;
                                _slip_residual += interaction_slip_residual*interaction_slip_residual;

                                if (state == SLIPPING || state == SLIPPED_TOO_FAR)
                                {
                                    _num_slipping++;
                                    if (state == SLIPPED_TOO_FAR)
                                        _num_slipped_too_far++;
                                    for (unsigned int i=0; i<dim; ++i)
                                    {
                                        SlipData sd(node,i,slip_iterative(i));
                                        if (iterative_slip)
                                            iterative_slip->push_back(sd);
                                        _it_slip_norm += slip_iterative(i)*slip_iterative(i);
                                        _inc_slip_norm += (slip_inc_vec(i)+slip_iterative(i))*(slip_inc_vec(i)+slip_iterative(i));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        _communicator.sum(_num_contact_nodes);
        _communicator.sum(_num_slipping);
        _communicator.sum(_num_slipped_too_far);
        _communicator.sum(_slip_residual);
        _slip_residual = std::sqrt(_slip_residual);
        _communicator.sum(_it_slip_norm);
        _it_slip_norm = std::sqrt(_it_slip_norm);
        _communicator.sum(_inc_slip_norm);
        _inc_slip_norm = std::sqrt(_inc_slip_norm);
        if (_num_slipping > 0)
            updatedSolution = true;
    }

    return updatedSolution;
}
コード例 #10
0
ファイル: HeightMipmap.cpp プロジェクト: paladin74/proland
void HeightMipmap::buildResiduals(int level)
{
    int nTiles = max(1, (baseLevelSize / this->tileSize) >> (maxLevel - level));
    int nTilesPerFile = min(nTiles, 16);
    int tileSize = min(topLevelSize << level, this->tileSize);

    printf("Build residuals level %d...\n", level);

    currentLevel = level;
    reset(baseLevelSize >> (maxLevel - currentLevel), baseLevelSize >> (maxLevel - currentLevel), min(topLevelSize << currentLevel, this->tileSize));

    float *parentTile = new float[(this->tileSize + 5) * (this->tileSize + 5)];
    float *currentTile = new float[(this->tileSize + 5) * (this->tileSize + 5)];
    float *residualTile = new float[(this->tileSize + 5) * (this->tileSize + 5)];
    unsigned char *encodedResidual = new unsigned char[(this->tileSize + 5) * (this->tileSize + 5) * 2];

    float maxRR = 0.0;
    float maxEE = 0.0;
    for (int dy = 0; dy < nTiles / nTilesPerFile; ++dy) {
        for (int dx = 0; dx < nTiles / nTilesPerFile; ++dx) {
            char buf[256];
            sprintf(buf, "%s/residual-%.2d-%.4d-%.4d.tiff", cache.c_str(), level, dx, dy);

            if (flog(buf)) {
                TIFF* f = TIFFOpen(buf, "wb");
                for (int ny = 0; ny < nTilesPerFile; ++ny) {
                    for (int nx = 0; nx < nTilesPerFile; ++nx) {
                        int tx = nx + dx * nTilesPerFile;
                        int ty = ny + dy * nTilesPerFile;
                        float maxR, meanR, maxErr;

                        getApproxTile(level - 1, tx / 2, ty / 2, parentTile);
                        getTile(level, tx, ty, currentTile);
                        computeResidual(parentTile, currentTile, level, tx, ty, residualTile, maxR, meanR);
                        encodeResidual(level, residualTile, encodedResidual);
                        computeApproxTile(parentTile, residualTile, level, tx, ty, currentTile, maxErr);
                        if (level < maxLevel) {
                            saveApproxTile(level, tx, ty, currentTile);
                        }

                        TIFFSetField(f, TIFFTAG_IMAGEWIDTH, tileSize + 5);
                        TIFFSetField(f, TIFFTAG_IMAGELENGTH, tileSize + 5);
                        TIFFSetField(f, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
                        TIFFSetField(f, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
                        TIFFSetField(f, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
                        TIFFSetField(f, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
                        /*TIFFSetField(f, TIFFTAG_SAMPLESPERPIXEL, 1);
                        TIFFSetField(f, TIFFTAG_BITSPERSAMPLE, 16);*/
                        TIFFSetField(f, TIFFTAG_SAMPLESPERPIXEL, 2);
                        TIFFSetField(f, TIFFTAG_BITSPERSAMPLE, 8);
                        TIFFWriteEncodedStrip(f, 0, encodedResidual, (tileSize + 5) * (tileSize + 5) * 2);
                        TIFFWriteDirectory(f);

                        maxRR = max(maxR, maxRR);
                        maxEE = max(maxErr, maxEE);
                    }
                }

                TIFFClose(f);
                printf("%f max residual, %f max err\n", maxRR, maxEE);
            }
        }
    }

    delete[] parentTile;
    delete[] currentTile;
    delete[] residualTile;
    delete[] encodedResidual;
}
コード例 #11
0
ファイル: solver.cpp プロジェクト: feelX46/NumSim
void Solver::SORCycle(GridFunction* gridfunction,
			  GridFunctionType& rhs,
			  const PointType& h){

	MultiIndexType dim = gridfunction->GetGridDimension();
	MultiIndexType bread  (0,0);
	MultiIndexType eread  (dim[0]-1,dim[1]-1);
	MultiIndexType bwrite (1,1);
	MultiIndexType ewrite (dim[0]-2,dim[1]-2);

	Computation pc (param);

	//Initialization of the residual. Just choose a value, that should be a bad error.
	RealType res = 10e20;
	int iterationCounter = 0;
	// SOR-cycling until error is small enough, or the number of iterations gets to high:
	RealType neighbours_x, neighbours_y;

	/*
	 std::cout<<"direct before SOR:" <<std::endl;
	 gridfunction->PlotGrid();
	 std::cout<<std::endl;
     */

	while (iterationCounter < param.iterMax && res > param.eps )
	{

		pc.setBoundaryP(*gridfunction);

		/*
		std::cout<<"after boundary-setting:" <<std::endl;
		gridfunction->PlotGrid();
		std::cout<<std::endl;
		*/

		 for (IndexType i = 1; i <= dim[0]-2; i++)
		{
			for (IndexType j = 1; j <= dim[1]-2; j++)
			{
				//help-values "neighbours_x" and "neighbours_y" for better overview
				neighbours_x = (gridfunction->GetGridFunction()[i+1][j] + gridfunction->GetGridFunction()[i-1][j])
									  / h[0] / h[0];
				neighbours_y = (gridfunction->GetGridFunction()[i][j+1] + gridfunction->GetGridFunction()[i][j-1])
											  / h[1] / h[1];
				//SOR-iteration
				gridfunction->SetGridFunction(i,j,(1.0 - param.omg)*gridfunction->GetGridFunction()[i][j]
							 + param.omg /(2.0*(1/h[0]/h[0]+1/h[1]/h[1]))
							 * (neighbours_x + neighbours_y - rhs[i][j]));
			}
		}
		iterationCounter++;
		pc.setBoundaryP(*gridfunction);
		res = computeResidual(*gridfunction, rhs, h);

		/*
		std::cout<<"after SOR:" <<std::endl;
		gridfunction->PlotGrid();
		std::cout<<std::endl;
		*/
	}
	if (iterationCounter >= param.iterMax)
		std::cout<<"iteration abort with error res = "<<res<<std::endl;

}
コード例 #12
0
ファイル: ReturnMappingModel.C プロジェクト: Liuux/moose
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);
}
コード例 #13
0
ファイル: ReturnMappingModel.C プロジェクト: Teslos/moose
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);

}