Mentions légales du service

Skip to content
Snippets Groups Projects
Forked from Martin Genet / dolfin_warp
279 commits behind the upstream repository.
generated_grad_expressions_cpp.py 5.18 KiB
#coding=utf8

################################################################################
###                                                                          ###
### Created by Martin Genet, 2016-2019                                       ###
###                                                                          ###
### École Polytechnique, Palaiseau, France                                   ###
###                                                                          ###
################################################################################

################################################################################

def get_ExprGenGrad_cpp(
        im_dim,
        im_type="grad",
        im_is_def=0,
        disp_type="fenics", # "vtk"
        verbose=0):

    assert (im_dim in (2,3))
    assert (im_type in ("grad"))

    ExprGenGrad_cpp = '''\
#include <string.h>

#include <vtkSmartPointer.h>
#include <vtkStructuredPointsReader.h>
#include <vtkXMLImageDataReader.h>
#include <vtkImageData.h>
#include <vtkImageGradient.h>
#include <vtkImageInterpolator.h>

double getStaticScalingFactor(const char* scalar_type_as_string)
{
    if (strcmp(scalar_type_as_string, "unsigned char" ) == 0) return pow(2,  8)-1;
    if (strcmp(scalar_type_as_string, "unsigned short") == 0) return pow(2, 16)-1;
    if (strcmp(scalar_type_as_string, "unsigned int"  ) == 0) return pow(2, 32)-1;
    if (strcmp(scalar_type_as_string, "unsigned long" ) == 0) return pow(2, 64)-1;
    if (strcmp(scalar_type_as_string, "float"         ) == 0) return 1.;
    if (strcmp(scalar_type_as_string, "double"        ) == 0) return 1.;
    assert (0);
}

namespace dolfin
{

class MyExpr : public Expression
{
    vtkSmartPointer<vtkImageData> image;
    vtkSmartPointer<vtkImageGradient> gradient;
    vtkSmartPointer<vtkImageInterpolator> interpolator;
    double static_scaling;
    std::shared_ptr<dolfin::Mesh> mesh;
    std::shared_ptr<dolfin::Function> U;
    mutable Array<double> UX;
    mutable Array<double> x;

public:

    MyExpr():
        Expression('''+str(im_dim)*(im_type in ("grad"))+'''),
        UX('''+str(im_dim)+'''),
        x(3),
        interpolator(vtkSmartPointer<vtkImageInterpolator>::New())

    {
    }

    void init_mesh(
        const std::shared_ptr<dolfin::Mesh> mesh_)
    {
        mesh = mesh_;

        std::cout << mesh->num_vertices() << std::endl;
        std::cout << mesh->num_cells() << std::endl;
    }

    void init_disp(
        const std::shared_ptr<dolfin::Function> U_)
    {
        U = U_;
    }

    void init_image()
    {
        image = vtkSmartPointer<vtkImageData>::New(); // MG20180913: another way to instantiate object
        gradient = vtkSmartPointer<vtkImageGradient>::New();
    }



    void eval(Array<double>& expr, const Array<double>& X) const
    {'''+('''

        std::cout << "X = " << X.str(1) << std::endl;''')*(verbose)+'''

        U->eval(UX, X);'''+('''
        std::cout << "UX = " << UX.str(1) << std::endl;''')*(verbose)+('''
        x[0] = X[0] + UX[0];
        x[1] = X[1] + UX[1];''')*(im_dim==2)+('''
        x[0] = X[0] + UX[0];
        x[1] = X[1] + UX[1];
        x[2] = X[2] + UX[2];''')*(im_dim==3)+('''
        std::cout << "x = " << x.str(1) << std::endl;''')*(verbose)+'''

        interpolator->Interpolate(x.data(), expr.data());'''+('''
        std::cout << "expr = " << expr.str(1) << std::endl;''')*(verbose)+('''

        expr[0] /= static_scaling;''')*(im_type=="im")+('''

        expr[0] /= static_scaling;
        expr[1] /= static_scaling;''')*(im_type=="grad")*(im_dim==2)+('''

        expr[0] /= static_scaling;
        expr[1] /= static_scaling;
        expr[2] /= static_scaling;''')*(im_type=="grad")*(im_dim==3)+('''
        std::cout << "expr = " << expr.str(1) << std::endl;''')*(verbose)+'''
    }


    void prepareImage( int n1, int n2, int n3, float origin1, float origin2, float origin3, float spac1, float spac2, float spac3)
    {
        image->SetDimensions(n1,n2,n3);
        image->AllocateScalars(VTK_FLOAT,1);

        image->SetSpacing(spac1, spac2, spac3);
        image->SetOrigin(origin1, origin2, origin3);

        static_scaling = getStaticScalingFactor("double");
    }


    void assignValues( int i, int j, int k, float value)
    {
        image->SetScalarComponentFromFloat(i,j,k,0,value);
    }

    void setGradient_Interpol()
    {
        interpolator->SetInterpolationModeToLinear();
        interpolator->SetOutValue(.0);

        gradient->SetInputData(image);
        gradient->SetDimensionality('''+str(im_dim)+''');
        gradient->Update();
        interpolator->Initialize(gradient->GetOutput());

        interpolator->Update();
    }


    void prepareImage_2D( int n1, int n2, float origin1, float origin2, float spac1, float spac2)
    {
        const double &Z=0.;
        image->SetExtent(0, n1-1, 0, n2-1, 0, 0);

        image->AllocateScalars(VTK_FLOAT,1);

        image->SetSpacing(spac1, spac2, 1);
        image->SetOrigin(origin1, origin2, 0);

        static_scaling = getStaticScalingFactor("double");
        x[2] = Z;

    }


    void assignValues_2D( int i, int j, float value)
    {
        image->SetScalarComponentFromFloat(i,j,0,0,value);
    }
};

}'''
    #print ExprIm_cpp
    return ExprGenGrad_cpp