[FEM] add framework to scale result mesh values
- it seems that we will need to scale result values (probably for the Elmer Eigen solver) This PR adds the framework to do this. It is meant for Elmer but designed versatile.
This commit is contained in:
@@ -46,11 +46,14 @@ set(FemGui_LIBS
|
||||
|
||||
|
||||
generate_from_xml(ViewProviderFemMeshPy)
|
||||
generate_from_xml(ViewProviderFemPostPipelinePy)
|
||||
|
||||
|
||||
SET(Python_SRCS
|
||||
ViewProviderFemMeshPy.xml
|
||||
ViewProviderFemMeshPyImp.cpp
|
||||
ViewProviderFemPostPipelinePy.xml
|
||||
ViewProviderFemPostPipelinePyImp.cpp
|
||||
)
|
||||
SOURCE_GROUP("Python" FILES ${Python_SRCS})
|
||||
|
||||
|
||||
@@ -22,14 +22,20 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <vtkPointData.h>
|
||||
#endif
|
||||
|
||||
#include <App/FeaturePythonPyImp.h>
|
||||
#include <App/GroupExtension.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Mod/Fem/App/FemAnalysis.h>
|
||||
#include <Mod/Fem/App/FemPostPipeline.h>
|
||||
|
||||
#include "ViewProviderAnalysis.h"
|
||||
#include "ViewProviderFemPostPipeline.h"
|
||||
#include "ViewProviderFemPostPipelinePy.h"
|
||||
#include "ViewProviderAnalysis.h"
|
||||
#include "ViewProviderFemPostFunction.h"
|
||||
|
||||
|
||||
@@ -122,3 +128,69 @@ void ViewProviderFemPostPipeline::onSelectionChanged(const Gui::SelectionChanges
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderFemPostPipeline::transformField(char *FieldName, double FieldFactor)
|
||||
{
|
||||
Fem::FemPostPipeline *obj = static_cast<Fem::FemPostPipeline *>(getObject());
|
||||
|
||||
vtkSmartPointer<vtkDataObject> data = obj->Data.getValue();
|
||||
if (!data || !data->IsA("vtkDataSet"))
|
||||
return;
|
||||
|
||||
vtkDataSet *dset = vtkDataSet::SafeDownCast(data);
|
||||
vtkDataArray *pdata = dset->GetPointData()->GetArray(FieldName);
|
||||
if (!pdata)
|
||||
return;
|
||||
|
||||
auto strFieldName = std::string(FieldName);
|
||||
|
||||
// for EigenModes, we need to step through all available modes
|
||||
if (strFieldName.find("EigenMode") != std::string::npos) {
|
||||
int modeCount;
|
||||
std::string testFieldName;
|
||||
// since a valid FieldName must have been passed
|
||||
// we assume the mode number was < 10 and we can strip the last char
|
||||
strFieldName.pop_back();
|
||||
for (modeCount = 1; pdata; ++modeCount) {
|
||||
testFieldName = strFieldName + std::to_string(modeCount);
|
||||
pdata = dset->GetPointData()->GetArray(testFieldName.c_str());
|
||||
if (pdata) {
|
||||
scaleField(dset, pdata, FieldFactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
scaleField(dset, pdata, FieldFactor);
|
||||
}
|
||||
|
||||
void ViewProviderFemPostPipeline::scaleField(vtkDataSet *dset, vtkDataArray *pdata, double FieldFactor)
|
||||
{
|
||||
//safe guard
|
||||
if (!dset || !pdata)
|
||||
return;
|
||||
|
||||
// step through all mesh points and scale them
|
||||
for (int i = 0; i < dset->GetNumberOfPoints(); ++i) {
|
||||
double value = 0;
|
||||
if (pdata->GetNumberOfComponents() == 1) {
|
||||
value = pdata->GetComponent(i, 0);
|
||||
pdata->SetComponent(i, 0, value * FieldFactor);
|
||||
}
|
||||
// if field is a vector
|
||||
else {
|
||||
for (int j = 0; j < pdata->GetNumberOfComponents(); ++j) {
|
||||
value = pdata->GetComponent(i, j);
|
||||
pdata->SetComponent(i, j, value * FieldFactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *ViewProviderFemPostPipeline::getPyObject(void)
|
||||
{
|
||||
if (PythonObject.is(Py::_None())) {
|
||||
// ref counter is set to 1
|
||||
PythonObject = Py::Object(new ViewProviderFemPostPipelinePy(this), true);
|
||||
}
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#define FEM_VIEWPROVIDERFEMPOSTPIPELINE_H
|
||||
|
||||
#include "ViewProviderFemPostObject.h"
|
||||
#include <Gui/ViewProviderPythonFeature.h>
|
||||
#include <Mod/Fem/FemGlobal.h>
|
||||
|
||||
namespace FemGui
|
||||
{
|
||||
@@ -42,6 +44,12 @@ public:
|
||||
virtual std::vector< App::DocumentObject* > claimChildren3D(void) const;
|
||||
virtual void updateData(const App::Property* prop);
|
||||
virtual void onSelectionChanged(const Gui::SelectionChanges &sel);
|
||||
void transformField(char *FieldName, double FieldFactor);
|
||||
void scaleField(vtkDataSet *dset, vtkDataArray *pdata, double FieldFactor);
|
||||
PyObject *getPyObject();
|
||||
|
||||
private:
|
||||
Py::Object PythonObject;
|
||||
|
||||
protected:
|
||||
void updateFunctionSize();
|
||||
|
||||
24
src/Mod/Fem/Gui/ViewProviderFemPostPipelinePy.xml
Normal file
24
src/Mod/Fem/Gui/ViewProviderFemPostPipelinePy.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="ViewProviderDocumentObjectPy"
|
||||
Name="ViewProviderFemPostPipelinePy"
|
||||
Twin="ViewProviderFemPostPipeline"
|
||||
TwinPointer="ViewProviderFemPostPipeline"
|
||||
Include="Mod/Fem/Gui/ViewProviderFemPostPipeline.h"
|
||||
Namespace="FemGui"
|
||||
FatherInclude="Gui/ViewProviderDocumentObjectPy.h"
|
||||
FatherNamespace="Gui"
|
||||
Constructor="false"
|
||||
Delete="false">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Uwe Stöhr" EMail="uwestoehr@lyx.org" />
|
||||
<UserDocu>ViewProviderFemPostPipeline class</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="transformField">
|
||||
<Documentation>
|
||||
<UserDocu></UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
64
src/Mod/Fem/Gui/ViewProviderFemPostPipelinePyImp.cpp
Normal file
64
src/Mod/Fem/Gui/ViewProviderFemPostPipelinePyImp.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Uwe Stöhr <uwestoehr@lyx.org> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <Base/VectorPy.h>
|
||||
#include <Base/GeometryPyCXX.h>
|
||||
|
||||
#include "ViewProviderFemPostPipeline.h"
|
||||
|
||||
// inclusion of the generated files (generated out of ViewProviderFemPostPipelinePy.xml)
|
||||
#include "ViewProviderFemPostPipelinePy.h"
|
||||
#include "ViewProviderFemPostPipelinePy.cpp"
|
||||
|
||||
|
||||
using namespace FemGui;
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string ViewProviderFemPostPipelinePy::representation(void) const
|
||||
{
|
||||
return std::string("<ViewProviderFemPostPipeline object>");
|
||||
}
|
||||
|
||||
PyObject *ViewProviderFemPostPipelinePy::transformField(PyObject *args)
|
||||
{
|
||||
char *FieldName;
|
||||
double FieldFactor;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sd", &FieldName, &FieldFactor))
|
||||
return nullptr;
|
||||
|
||||
this->getViewProviderFemPostPipelinePtr()->transformField(FieldName, FieldFactor);
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject *ViewProviderFemPostPipelinePy::getCustomAttributes(const char * /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int ViewProviderFemPostPipelinePy::setCustomAttributes(const char * /*attr*/, PyObject * /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -255,6 +255,11 @@ class Results(run.Results):
|
||||
# at the moment we scale the mesh back using Elmer
|
||||
# this might be changed in future, therefore leave this
|
||||
# self.solver.ElmerResult.scale(1000)
|
||||
|
||||
# it might be necessary to scale some result fields
|
||||
# this would be done by this call:
|
||||
# self.solver.ElmerResult.ViewObject.transformField("displacement EigenMode1", 0.001)
|
||||
|
||||
self.solver.ElmerResult.recomputeChildren()
|
||||
self.solver.Document.recompute()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user