Commit 5051a446 authored by Douglas Serson's avatar Douglas Serson
Browse files

Merge branch 'feature/fieldfromstring' into 'master'

turn addfieldfromstring into fieldfromstring and enable modifying existing fields

See merge request !903
parents 9928d6f3 925d1e68
......@@ -71,7 +71,7 @@ v5.0.0
- Enable output to multiple files (!844)
- Allow using xml file without expansion tag in FieldConvert (!849)
- Add Lambda 2 vortex detection criteria (!882)
- Add module for calculating new field from existing ones (!889)
- Add module for modifying/adding fields from expressions (!889, !903)
- Add module for evaluating the mean of variables on the domain (!894)
**IncNavierStokesSolver**
......
......@@ -157,7 +157,7 @@ Specifically, FieldConvert has these additional functionalities
\item \inltt{QCriterion}: Computes the Q-Criterion for a given output file;
\item \inltt{L2Criterion}: Computes the Lambda 2 Criterion for a given output file;
\item \inltt{addcompositeid}: Adds the composite ID of an element as an additional field;
\item \inltt{addfieldfromstring}: Adds a new field from an expression involving the existing fields;
\item \inltt{fieldfromstring}: Modifies or adds a new field from an expression involving the existing fields;
\item \inltt{addFld}: Sum two .fld files;
\item \inltt{combineAvg}: Combine two \nekpp binary output (.chk or .fld) field file containing averages of fields (and
possibly also Reynolds stresses) into single file;
......@@ -286,18 +286,18 @@ obtained through the \nm \inltt{extract} module (see section
%
%
%
\subsection{Add new field: \textit{addfieldfromstring} module}
To create a new field using an expression involving the existing fields, one can
use the \inltt{addfieldfromstring} module of FieldConvert
\subsection{Add new field: \textit{fieldfromstring} module}
To modify or create a new field using an expression involving the existing fields, one can
use the \inltt{fieldfromstring} module of FieldConvert
%
\begin{lstlisting}[style=BashInputStyle]
FieldConvert -m addfieldfromstring:fieldstr="x+y+u":fieldname="result" \
FieldConvert -m fieldfromstring:fieldstr="x+y+u":fieldname="result" \
file1.xml file2.fld file3.fld
\end{lstlisting}
%
In this case \inltt{fieldstr} is a required parameter describing a function of
the coordinates and the existing variables, and \inltt{fieldname} is an optional
parameter defining the name of the new field (the default is newfield).
parameter defining the name of the new or modified field (the default is newfield).
\inltt{file3.fld} is the output containing both the original and the new fields,
and can be processed in a similar way as described
in section \ref{s:utilities:fieldconvert:sub:convert} to visualise
......
......@@ -17,7 +17,7 @@ SET(FieldUtilsHeaders
OutputModules/OutputPts.h
OutputModules/OutputXml.h
ProcessModules/ProcessAddCompositeID.h
ProcessModules/ProcessAddFieldFromString.h
ProcessModules/ProcessFieldFromString.h
ProcessModules/ProcessAddFld.h
ProcessModules/ProcessBoundaryExtract.h
ProcessModules/ProcessCombineAvg.h
......@@ -73,7 +73,7 @@ SET(FieldUtilsSources
OutputModules/OutputPts.cpp
OutputModules/OutputXml.cpp
ProcessModules/ProcessAddCompositeID.cpp
ProcessModules/ProcessAddFieldFromString.cpp
ProcessModules/ProcessFieldFromString.cpp
ProcessModules/ProcessAddFld.cpp
ProcessModules/ProcessBoundaryExtract.cpp
ProcessModules/ProcessCombineAvg.cpp
......
///////////////////////////////////////////////////////////////////////////////
//
// File: ProcessAddFieldFromString.cpp
// File: ProcessFieldFromString.cpp
//
// For more information, please see: http://www.nektar.info/
//
......@@ -29,14 +29,14 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Add a new field from a string based on existing variable
// Description: Modify an existing or add a new field from a string based on existing variable
//
///////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
using namespace std;
#include "ProcessAddFieldFromString.h"
#include "ProcessFieldFromString.h"
#include <LibUtilities/BasicUtils/ParseUtils.h>
#include <LibUtilities/BasicUtils/SharedArray.hpp>
......@@ -46,28 +46,30 @@ namespace Nektar
namespace FieldUtils
{
ModuleKey ProcessAddFieldFromString::className =
ModuleKey ProcessFieldFromString::className =
GetModuleFactory().RegisterCreatorFunction(
ModuleKey(eProcessModule, "addfieldfromstring"),
ProcessAddFieldFromString::create,
"Create a new field from the existing fields as specified by a string"
" using a required argument of the form fieldstr=\"x + y + u\" ");
ModuleKey(eProcessModule, "fieldfromstring"),
ProcessFieldFromString::create,
"Modify an existing or create a new field from the existing fields as "
"specified by a string using a required argument of the form "
"fieldstr=\"x + y + u\" ");
ProcessAddFieldFromString::ProcessAddFieldFromString(FieldSharedPtr f)
ProcessFieldFromString::ProcessFieldFromString(FieldSharedPtr f)
: ProcessModule(f)
{
m_config["fieldstr"] = ConfigOption(
false, "NotSet", "string of new field to be added (required)");
false, "NotSet", "Analytic expression");
m_config["fieldname"] =
ConfigOption(false, "newfield",
"name for new field, default is newfield (optional)");
ConfigOption(false,
"newfield",
"name for modified new field, default is \"newfield\" (optional)");
}
ProcessAddFieldFromString::~ProcessAddFieldFromString(void)
ProcessFieldFromString::~ProcessFieldFromString(void)
{
}
void ProcessAddFieldFromString::Process(po::variables_map &vm)
void ProcessFieldFromString::Process(po::variables_map &vm)
{
// Check if required parameter fieldstr was provided
ASSERTL0(m_config["fieldstr"].m_beenSet, "fieldstr must be specified");
......@@ -77,7 +79,24 @@ void ProcessAddFieldFromString::Process(po::variables_map &vm)
// Set up new field name
string fieldName = m_config["fieldname"].as<string>();
m_f->m_variables.push_back(fieldName);
int fieldID;
bool addField;
// check if field exists
auto it =
std::find(m_f->m_variables.begin(), m_f->m_variables.end(), fieldName);
if (it != m_f->m_variables.end())
{
addField = false;
fieldID = std::distance(m_f->m_variables.begin(), it);
}
else
{
// Create new expansion
addField = true;
fieldID = nfields;
m_f->m_variables.push_back(fieldName);
}
// Skip in case of empty partition
if (m_f->m_exp[0]->GetNumElmts() == 0)
......@@ -91,13 +110,15 @@ void ProcessAddFieldFromString::Process(po::variables_map &vm)
ASSERTL0(nstrips == 1,
"Routine is currently only setup for non-strip files");
// Create new expansion
m_f->m_exp.resize(nfields + 1);
m_f->m_exp[nfields] = m_f->AppendExpList(m_f->m_numHomogeneousDir);
if (addField)
{
m_f->m_exp.resize(nfields + 1);
m_f->m_exp[nfields] = m_f->AppendExpList(m_f->m_numHomogeneousDir);
}
// Variables for storing names and values for evaluating the function
string varstr;
vector<Array<OneD, const NekDouble>> interpfields;
vector<Array<OneD, const NekDouble> > interpfields;
// Add the coordinate values
varstr += "x y z";
......@@ -124,11 +145,11 @@ void ProcessAddFieldFromString::Process(po::variables_map &vm)
exprId = strEval.DefineFunction(varstr.c_str(), fieldstr);
// Evaluate function
strEval.Evaluate(exprId, interpfields, m_f->m_exp[nfields]->UpdatePhys());
strEval.Evaluate(exprId, interpfields, m_f->m_exp[fieldID]->UpdatePhys());
// Update coeffs
m_f->m_exp[nfields]->FwdTrans_IterPerExp(
m_f->m_exp[nfields]->GetPhys(), m_f->m_exp[nfields]->UpdateCoeffs());
m_f->m_exp[fieldID]->FwdTrans_IterPerExp(
m_f->m_exp[fieldID]->GetPhys(), m_f->m_exp[fieldID]->UpdateCoeffs());
}
}
}
///////////////////////////////////////////////////////////////////////////////
//
// File: ProcessAddFieldFromString.h
// File: ProcessFieldFromString.h
//
// For more information, please see: http://www.nektar.info/
//
......@@ -33,8 +33,8 @@
//
////////////////////////////////////////////////////////////////////////////////
#ifndef FIELDUTILS_PROCESSADDNEWFIELDFROMSTR
#define FIELDUTILS_PROCESSADDNEWFIELDFROMSTR
#ifndef FIELDUTILS_PROCESSFIELDFROMSTR
#define FIELDUTILS_PROCESSFIELDFROMSTR
#include "../Module.h"
......@@ -46,24 +46,24 @@ namespace FieldUtils
/**
* @brief This processing module adds a new field from a string definition
*/
class ProcessAddFieldFromString : public ProcessModule
class ProcessFieldFromString : public ProcessModule
{
public:
/// Creates an instance of this class
static std::shared_ptr<Module> create(FieldSharedPtr f)
{
return MemoryManager<ProcessAddFieldFromString>::AllocateSharedPtr(f);
return MemoryManager<ProcessFieldFromString>::AllocateSharedPtr(f);
}
static ModuleKey className;
ProcessAddFieldFromString(FieldSharedPtr f);
virtual ~ProcessAddFieldFromString();
ProcessFieldFromString(FieldSharedPtr f);
virtual ~ProcessFieldFromString();
virtual void Process(po::variables_map &vm);
virtual std::string GetModuleName()
{
return "ProcessAddFieldFromString";
return "ProcessFieldFromString";
}
virtual std::string GetModuleDescription()
......
......@@ -20,6 +20,7 @@ ADD_NEKTAR_TEST(chan3D_pts)
ADD_NEKTAR_TEST(chan3DH1D_meanmode)
ADD_NEKTAR_TEST(chan3DH1D_plane)
ADD_NEKTAR_TEST(chan3DH1D_stretch)
ADD_NEKTAR_TEST(chan3D_modp)
ADD_NEKTAR_TEST(chan3D_probe)
ADD_NEKTAR_TEST(cube_prismhex)
# ADD_NEKTAR_TEST(outflow_pointdatatofld) # need to redefine outflow.pts since GetOffsetElmtId
......
<?xml version="1.0" encoding="utf-8"?>
<test>
<description> Convert a .pts file to .dat </description>
<executable>FieldConvert</executable>
<parameters> -f -e -m fieldfromstring:fieldstr="p*x+y":fieldname="p" chan3D.xml chan3D.fld chan3D_modp.csv</parameters>
<files>
<file description="Session File">chan3D.xml</file>
<file description="Session File">chan3D.fld</file>
</files>
<metrics>
<metric type="L2" id="1">
<value variable="x" tolerance="1e-6">1.63299</value>
<value variable="y" tolerance="1e-6">1.63299</value>
<value variable="z" tolerance="1e-6">1.63299</value>
<value variable="u" tolerance="1e-6">2.06559</value>
<value variable="v" tolerance="1e-5">0</value>
<value variable="w" tolerance="1e-5">0</value>
<value variable="p" tolerance="1e-5">4.44222</value>
</metric>
</metrics>
</test>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment