Пример #1
0
void gcm::LineFirstOrderInterpolator::interpolate(CalcNode& node, CalcNode& node0, CalcNode& node1)
{
    LOG_TRACE("Start interpolation");

    float lenTotal = distance(node0.coords, node1.coords);

    float factor0 = distance(node.coords, node1.coords) / lenTotal;

    float factor1 = distance(node.coords, node0.coords) / lenTotal;

    // If we see potential instability
    if (factor0 + factor1 > 1.0) {
        // If it is small - treat instability as minor and just 'smooth' it
        if (factor0 + factor1 < 1 + EQUALITY_TOLERANCE) // FIXME@avasyukov
        {
            float sum = factor0 + factor1;
            factor0 = factor0 / sum;
            factor1 = factor1 / sum;
        }
            // Throw exception
        else {
            LOG_ERROR("Requested node: " << node);
            LOG_ERROR("Node #1: " << node0);
            LOG_ERROR("Node #2: " << node1);
            LOG_ERROR("Factor: " << factor0 + factor1);
            THROW_BAD_MESH("Sum of factors is greater than 1.0");
        }
    }

    for (int i = 0; i < 9; i++) {
        node.values[i] = (node0.values[i] * factor0 + node1.values[i] * factor1);
    }

    node.setRho(node0.getRho() * factor0 + node1.getRho() * factor1);
    node.setMaterialId(node0.getMaterialId());

    LOG_TRACE("Interpolation done");
}
void TetrFirstOrderInterpolator::interpolate(CalcNode& node, CalcNode& node0, CalcNode& node1, CalcNode& node2, CalcNode& node3)
{
    LOG_TRACE("Start interpolation");

    float Vol = tetrVolume(
                           (node1.coords[0])-(node0.coords[0]),
                           (node1.coords[1])-(node0.coords[1]),
                           (node1.coords[2])-(node0.coords[2]),
                           (node2.coords[0])-(node0.coords[0]),
                           (node2.coords[1])-(node0.coords[1]),
                           (node2.coords[2])-(node0.coords[2]),
                           (node3.coords[0])-(node0.coords[0]),
                           (node3.coords[1])-(node0.coords[1]),
                           (node3.coords[2])-(node0.coords[2])
                           );

    float factor[4];

    factor[0] = fabs(tetrVolume(
                                (node1.coords[0])-(node.coords[0]),
                                (node1.coords[1])-(node.coords[1]),
                                (node1.coords[2])-(node.coords[2]),
                                (node2.coords[0])-(node.coords[0]),
                                (node2.coords[1])-(node.coords[1]),
                                (node2.coords[2])-(node.coords[2]),
                                (node3.coords[0])-(node.coords[0]),
                                (node3.coords[1])-(node.coords[1]),
                                (node3.coords[2])-(node.coords[2])
                                ) / Vol);

    factor[1] = fabs(tetrVolume(
                                (node0.coords[0])-(node.coords[0]),
                                (node0.coords[1])-(node.coords[1]),
                                (node0.coords[2])-(node.coords[2]),
                                (node2.coords[0])-(node.coords[0]),
                                (node2.coords[1])-(node.coords[1]),
                                (node2.coords[2])-(node.coords[2]),
                                (node3.coords[0])-(node.coords[0]),
                                (node3.coords[1])-(node.coords[1]),
                                (node3.coords[2])-(node.coords[2])
                                ) / Vol);

    factor[2] = fabs(tetrVolume(
                                (node1.coords[0])-(node.coords[0]),
                                (node1.coords[1])-(node.coords[1]),
                                (node1.coords[2])-(node.coords[2]),
                                (node0.coords[0])-(node.coords[0]),
                                (node0.coords[1])-(node.coords[1]),
                                (node0.coords[2])-(node.coords[2]),
                                (node3.coords[0])-(node.coords[0]),
                                (node3.coords[1])-(node.coords[1]),
                                (node3.coords[2])-(node.coords[2])
                                ) / Vol);

    factor[3] = fabs(tetrVolume(
                                (node1.coords[0])-(node.coords[0]),
                                (node1.coords[1])-(node.coords[1]),
                                (node1.coords[2])-(node.coords[2]),
                                (node2.coords[0])-(node.coords[0]),
                                (node2.coords[1])-(node.coords[1]),
                                (node2.coords[2])-(node.coords[2]),
                                (node0.coords[0])-(node.coords[0]),
                                (node0.coords[1])-(node.coords[1]),
                                (node0.coords[2])-(node.coords[2])
                                ) / Vol);

    // If we see potential instability
    if (factor[0] + factor[1] + factor[2] + factor[3] > 1.0) {
        // If it is small - treat instability as minor and just 'smooth' it
        // TODO - think about it more carefully
        //if( point_in_tetr(node.local_num, node.coords[0], node.coords[1], node.coords[2], tetr) )
        if (factor[0] + factor[1] + factor[2] + factor[3] < 1.05) // FIXME@avasyukov
        {
            //if (factor[0] + factor[1] + factor[2] + factor[3] > 5.0)
            //    LOG_ERROR("Factor: " << factor[0] + factor[1] + factor[2] + factor[3]);
            float sum = factor[0] + factor[1] + factor[2] + factor[3];
            for (int i = 0; i < 4; i++)
                factor[i] = factor[i] / sum;
        }
            // If point is not in tetr - throw exception
        else {
            /*            *logger << "\tTetrVol = " < Vol;
             *logger << "\tfactor[0]=" << factor[0] << " factor[1]=" << factor[1] << " factor[2]=" << factor[2]     << " factor[3]=" << factor[3] << " Sum: " < factor[0] + factor[1] + factor[2] + factor[3];

             *logger << "\tnode.coords.x[0]=" << node.coords[0] << " node.coords.x[1]=" << node.coords[1]
                                            << " node.coords.x[2]=" < node.coords[2];
                                    if( node.isFirstOrder() )
             *logger < "First order node";
                                    else if( node.isSecondOrder() )
             *logger < "Second order node";

             *logger << "\tv0.x[0]=" << nodes[tetr.vert[0]].coords[0] << " v0.x[1]=" << nodes[tetr.vert[0]].coords[1] << " v0.x[2]=" < nodes[tetr.vert[0]].coords[2];

             *logger << "\tv1.x[0]=" << nodes[tetr.vert[1]].coords[0] << " v1.x[1]=" << nodes[tetr.vert[1]].coords[1] << " v1.x[2]=" < nodes[tetr.vert[1]].coords[2];

             *logger << "\tv2.x[0]=" << nodes[tetr.vert[2]].coords[0] << " v2.x[1]=" << nodes[tetr.vert[2]].coords[1] << " v2.x[2]=" < nodes[tetr.vert[2]].coords[2];

             *logger << "\tv3.x[0]=" << nodes[tetr.vert[3]].coords[0] << " v3.x[1]=" << nodes[tetr.vert[3]].coords[1] << " v3.x[2]=" < nodes[tetr.vert[3]].coords[2];*/
            LOG_ERROR("Requested node: " << node);
            LOG_ERROR("Node #1: " << node0);
            LOG_ERROR("Node #2: " << node1);
            LOG_ERROR("Node #3: " << node2);
            LOG_ERROR("Node #4: " << node3);
            LOG_ERROR("Factor: " << factor[0] + factor[1] + factor[2] + factor[3]);
            THROW_BAD_MESH("Sum of factors is greater than 1.0");
        }
    }

    for (int i = 0; i < 9; i++) {
        node.values[i] = (node0.values[i] * factor[0]
                + node1.values[i] * factor[1]
                + node2.values[i] * factor[2]
                + node3.values[i] * factor[3]);
    }

    node.setRho(node0.getRho() * factor[0] + node1.getRho() * factor[1]
                + node2.getRho() * factor[2] + node3.getRho() * factor[3]);
    node.setMaterialId(node0.getMaterialId());

    LOG_TRACE("Interpolation done");
}