Forked from
Martin Genet / dolfin_warp
279 commits behind the upstream repository.
-
Martin Genet authoredMartin Genet authored
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