Пример #1
0
Matrix GeneratePhiDemagTensor(
	int dim_x, int dim_y, int dim_z, 
	double delta_x, double delta_y, double delta_z, 
	bool periodic_x, bool periodic_y, bool periodic_z, int periodic_repeat,
	int padding,
	const char *cache_dir)
{
	int exp_x = round_tensor_dimension(dim_x, periodic_x, padding);
	int exp_y = round_tensor_dimension(dim_y, periodic_y, padding);
	int exp_z = round_tensor_dimension(dim_z, periodic_z, padding);

	// also pad if exp_i = 1
	if (exp_x == 1) exp_x = 2;
	if (exp_y == 1) exp_y = 2;
	if (exp_z == 1) exp_z = 2;

	LOG_INFO  << "Preparing scalar potential tensor.";
	LOG_DEBUG << "  Magn. size: " << dim_x << "x" << dim_y << "x" << dim_z;
	LOG_DEBUG << "  Zeropadded: " << exp_x << "x" << exp_y << "x" << exp_z;
	LOG_DEBUG << "Periodic boundary conditions:";
	LOG_DEBUG << "  Dimensions : " << (periodic_x ? "x" : "") << (periodic_y ? "y" : "") << (periodic_z ? "z" : "");
	LOG_DEBUG << "  Repetitions: " << periodic_repeat;

	if (periodic_x || periodic_y || periodic_z) {
		throw std::runtime_error("Demag potential tensor field calculation for periodic boundary conditions not yet supported");
	}

	Matrix S(Shape(3, exp_x, exp_y, exp_z));
	S.clear();

	if (std::getenv("MAGNUM_DEMAG_GARBAGE")) {
		LOG_INFO << "Skipping phi tensor generation ('MAGNUM_GARBAGE' environment variable is set!)";
		return S;
	}

	LOG_DEBUG<< "Generating...";

	Matrix::wo_accessor S_acc(S);

	int cnt = 0, percent = 0;
	for (int z=0; z<exp_z; ++z)
	for (int y=0; y<exp_y; ++y) {
		for (int x=0; x<exp_x; ++x) {
			// position delta (in number of cells)
			const int dx = x - dim_x + 1;
			const int dy = y - dim_y + 1;
			const int dz = z - dim_z + 1;

			/*if (dx >= dim_x+1) continue;
			if (dy >= dim_y+1) continue;
			if (dz >= dim_z+1) continue;*/

			// position delta (in nanometer)
			const double diff_x = dx * delta_x - 0.5*delta_x;
			const double diff_y = dy * delta_y - 0.5*delta_y;
			const double diff_z = dz * delta_z - 0.5*delta_z;
			
			// store Nij at modulo position
			const int X = (dx + 2*exp_x) % exp_x;
			const int Y = (dy + 2*exp_y) % exp_y;
			const int Z = (dz + 2*exp_z) % exp_z;

			// insert components (all real)
			Vector3d S_i(
				- demag_phi_coeff::getS<long double>(0, diff_x, diff_y, diff_z, delta_x, delta_y, delta_z),
				- demag_phi_coeff::getS<long double>(1, diff_x, diff_y, diff_z, delta_x, delta_y, delta_z),
				- demag_phi_coeff::getS<long double>(2, diff_x, diff_y, diff_z, delta_x, delta_y, delta_z)
			);
			S_acc.at(0, X, Y, Z) = S_i.x;
			S_acc.at(1, X, Y, Z) = S_i.y;
			S_acc.at(2, X, Y, Z) = S_i.z;
		}

		cnt += 1;
		if (100 * cnt / (exp_y*exp_z) > percent) {
			LOG_DEBUG << " * " << percent << "%";
			percent += 10;
		}
	}

	LOG_INFO << "Done.";
	return S;
}
Пример #2
0
//------------------------------------------------------------------------------
void ADRmohrCoulombFracture::evaluateStepTwo(const pair<int, int> &id_col)
{
    // First calculating the total stress on an material point. The stress is averaged
    // all its bonds, and the stress state on a bond is the mean of the
    // stress at each material point.

    const int id_i = id_col.first;
    const int col_i = id_col.second;

    if((*m_data)(col_i, m_indexUnbreakable) >= 1)
        return;

    vector<pair<int, vector<double>>> & PDconnections = m_particles->pdConnections(id_i);

    /*
    if(m_dim == 2)
    {
        arma::mat S_i(2, 2);
        arma::mat S(2, 2);
        S_i(0, 0) = (*m_data)(col_i, m_indexStress[0]);
        S_i(1, 1) = (*m_data)(col_i, m_indexStress[1]);
        S_i(0, 1) = (*m_data)(col_i, m_indexStress[3]);
        S_i(1, 0) = S_i(0, 1);
        arma::vec eigval;

        for(auto &con:PDconnections)
        {
            const int id_j = con.first;
            const int j = (*m_pIds)[id_j];

            if((*m_data)(j, m_indexUnbreakable) >= 1)
                continue;

            if(con.second[m_indexConnected] <= 0.5)
                continue;

            S(0, 0) = 0.5*(S_i(0, 0) + (*m_data)(j, m_indexStress[0]));
            S(1, 1) = 0.5*(S_i(1, 1) + (*m_data)(j, m_indexStress[1]));
            S(0, 1) = 0.5*(S_i(0, 1) + (*m_data)(j, m_indexStress[3]));
    //            S(0, 0) = max(S_i(0, 0), (*m_data)(j, m_indexStress[0]));
    //            S(1, 1) = max(S_i(1, 1), (*m_data)(j, m_indexStress[1]));
    //            S(0, 1) = max(S_i(0, 1), (*m_data)(j, m_indexStress[3]));
            S(1, 0) = S(0, 1);
            const double first = 0.5*(S(0, 0) + S(1, 1));
            const double second = sqrt(0.25*(S(0, 0) - S(1, 1))*(S(0, 0) - S(1, 1)) + S(0, 1)*S(0, 1));
            const double s1 = first + second;
            const double s2 = first - second;
            const double p_1 = max(s1, s2);
            const double p_2 = min(s1, s2);

    //            arma::eig_sym(eigval, S);
    //            const double p_1 = eigval(1);
    //            const double p_2 = eigval(0);

    //            if(m_d*p_1 - p_2 - m_C > 0)
    //            {
    //                con.second[m_indexConnected] = 0;
    //                m_maxPId = pair<int, pair<int, vector<double>> *>(id_i, &con);
    //            }
    //            else if(p_1 > m_T)
            if(p_1 > m_T)
            {
    //                con.second[m_indexConnected] = 0;
                if(p_1 > m_maxStress)
                {
                    m_maxPId = pair<int, pair<int, vector<double>> *>(id_i, &con);
                    m_maxStress = p_1;
                }
            }
        }
    }
    */
    arma::vec eigval(m_dim);
    arma::mat S_i(m_dim, m_dim);
    arma::mat S(m_dim, m_dim);

    if(m_dim == 2)
    {
        S_i(0, 0) = (*m_data)(col_i, m_indexStress[0]);
        S_i(1, 1) = (*m_data)(col_i, m_indexStress[1]);
        S_i(0, 1) = (*m_data)(col_i, m_indexStress[3]);
        S_i(1, 0) = S_i(0, 1);

        for(auto &con:PDconnections)
        {
            const int id_j = con.first;
            const int j = (*m_pIds)[id_j];

            if((*m_data)(j, m_indexUnbreakable) >= 1)
                continue;

            if(con.second[m_indexConnected] <= 0.5)
                continue;

            S(0, 0) = 0.5*(S_i(0, 0) + (*m_data)(j, m_indexStress[0]));
            S(1, 1) = 0.5*(S_i(1, 1) + (*m_data)(j, m_indexStress[1]));
            S(0, 1) = 0.5*(S_i(0, 1) + (*m_data)(j, m_indexStress[3]));
            S(1, 0) = S(0, 1);
#if 0
            arma::eig_sym(eigval, S);
            const double p_1 = eigval(1);
            const double p_2 = eigval(0);
#else
            const double first = 0.5*(S(0, 0) + S(1, 1));
            const double second = sqrt(0.25*(S(0, 0) - S(1, 1))*(S(0, 0) - S(1, 1)) + S(0, 1)*S(0, 1));
            const double s1 = first + second;
            const double s2 = first - second;
            const double p_1 = max(s1, s2);
            const double p_2 = min(s1, s2);
#endif

            if(m_d*p_1 - p_2 - m_C > 0)
            {
                con.second[m_indexConnected] = 0;
                m_maxPId = pair<int, pair<int, vector<double>> *>(id_i, &con);
            }
            else if(p_1 > m_T)
            {
                con.second[m_indexConnected] = 0;
                m_maxPId = pair<int, pair<int, vector<double>> *>(id_i, &con);
            }
        }
    }
    else if(m_dim == 3)
    {
        S_i(0, 0) = (*m_data)(col_i, m_indexStress[0]);
        S_i(1, 1) = (*m_data)(col_i, m_indexStress[1]);
        S_i(2, 2) = (*m_data)(col_i, m_indexStress[2]);
        S_i(0, 1) = (*m_data)(col_i, m_indexStress[3]);
        S_i(1, 0) = S_i(0, 1);
        S_i(0, 2) = (*m_data)(col_i, m_indexStress[4]);
        S_i(2, 0) = S_i(0, 2);
        S_i(1, 2) = (*m_data)(col_i, m_indexStress[5]);
        S_i(2, 1) = S_i(1, 2);

        for(auto &con:PDconnections)
        {
            const int id_j = con.first;
            const int col_j = (*m_pIds)[id_j];

            if((*m_data)(col_j, m_indexUnbreakable) >= 1)
                continue;

            if(con.second[m_indexConnected] <= 0.5)
                continue;

            S(0, 0) = 0.5*(S_i(0, 0) + (*m_data)(col_j, m_indexStress[0]));
            S(1, 1) = 0.5*(S_i(1, 1) + (*m_data)(col_j, m_indexStress[1]));
            S(2, 2) = 0.5*(S_i(2, 2) + (*m_data)(col_j, m_indexStress[2]));
            S(0, 1) = 0.5*(S_i(0, 1) + (*m_data)(col_j, m_indexStress[3]));
            S(1, 0) = S(0, 1);
            S(0, 2) = 0.5*(S_i(0, 2) + (*m_data)(col_j, m_indexStress[4]));
            S(2, 0) = S(0, 2);
            S(1, 2) = 0.5*(S_i(1, 2) + (*m_data)(col_j, m_indexStress[5]));
            S(2, 1) = S(1, 2);

#if 0
            arma::eig_sym(eigval, S);
            const double p_1 = eigval(2);
            const double p_2 = eigval(0);
#else
            const double I1 = S(0, 0) + S(1, 1) + S(2, 2);
            const double I2 = S(0, 0)*S(1, 1) + S(1, 1)*S(2, 2) + S(3, 3)*S(0, 0) - pow(S(0, 1), 2) - pow(S(1, 2), 2) - pow(S(0, 2), 2);
            const double I3 = S(0, 0)*S(1, 1)*S(2, 2) - S(0, 0)*pow(S(1, 2), 2) - S(1, 1)*pow(S(0, 2), 2) - S(2, 2)*pow(S(0, 1), 2) + 2*S(0, 1)*S(1, 2)*S(0, 2);
            const double phi = 1./3.*acos(0.5*(2*pow(I1, 3) -9*I1*I2 + 27*I3)/pow(pow(I1, 2) - 3*I2, 1.5));

            const double core = 2./3.*(sqrt(I1*I1 - 3*I2));
            const double s1 = I1/3. + core*cos(phi);
            const double s2 = I1/3. + core*cos(phi + 2.*M_PI/3.);
            const double s3 = I1/3. + core*cos(phi + 4.*M_PI/3.);

            double p_1 = s1;
            double p_2 = s2;

            if(s2>p_1)
            {
                p_1 = s2;
                p_2 = s1;
            }
            if(s3>p_1)
            {
                p_1 = s3;
            }
            else if(p_2 < s3) {
                p_2 = s3;
            }
#endif
            if(m_d*p_1 - p_2 - m_C > 0)
            {
                con.second[m_indexConnected] = 0;
                m_maxPId = pair<int, pair<int, vector<double>> *>(id_i, &con);
            }
            else if(p_1 > m_T)
            {
                con.second[m_indexConnected] = 0;
                m_maxPId = pair<int, pair<int, vector<double>> *>(id_i, &con);
            }
        }
    }
    //--------------------------------------------------------------------------
}