Commit 889bdb40 authored by Dave Moxey's avatar Dave Moxey

Merge branch 'feature/FC_AddCompositeID' into 'master'

New FC module to add composite ID as a field

This MR adds a FieldConvert module for adding the composite ID of the element to the output field. This is useful when many composites are present in the domain and need to be identified.

See merge request !674
parents 10317fe3 36afea31
......@@ -45,6 +45,7 @@ v4.4.0
- Move all modules to a new library, FieldUtils, to support post-processing
during simulations (!589)
- Add module to stretch homogeneous direction (!609)
- Add module to add composite ID of elements as a field (!674)
v4.3.4
------
......
......@@ -95,6 +95,7 @@ Specifically, FieldConvert has these additional functionalities
\begin{enumerate}
\item \inltt{C0Projection}: Computes the C0 projection of a given output file;
\item \inltt{QCriterion}: Computes the Q-Criterion for a given output file;
\item \inltt{addcompositeid}: Adds the composite ID of an element as an additional field;
\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;
......@@ -185,6 +186,22 @@ to visualise the result either in Tecplot, Paraview or VisIt.
%
%
\subsection{Add composite ID: \textit{addcompositeid} module}
When dealing with a geometry that has many surfaces, we need to identify the
composites to assign boundary conditions. To assist in this, FieldConvert has a
\inltt{addcompositeid} module, which adds the composite ID of every element as a
new field. To use this we simply run
%
\begin{lstlisting}[style=BashInputStyle]
FieldConvert -m addcompositeid mesh.xml out.dat
\end{lstlisting}
%
In this case, we have produced a Tecplot file which contains the mesh and a
variable that contains the composite ID. To assist in boundary identification,
the input file \inlsh{mesh.xml} should be a surface XML file that can be
obtained through the \mc \inltt{extract} module (see section
\ref{s:utilities:nekmesh:extract}).
\subsection{Sum two .fld files: \textit{addFld} module}
To sum two .fld files one can use the \inltt{addFld} module of FieldConvert
%
......
......@@ -297,19 +297,27 @@ In the rest of these subsections, we discuss the various processing modules
available within \mc.
\subsection{Extract surfaces from a mesh}
\label{s:utilities:nekmesh:extract}
To extract composite surfaces 2 and 3 from a mesh use the module \inltt{extract}
module:
Often one wants to visualise surfaces of a 3D mesh, or extract the values of
variables on the surface and visualise them. To support this, \mc can extract
two-dimensional surfaces which can be visualised using \inltt{FieldConvert} in
order to extract the value of a 3D field on a given surface.
As an example, we can extract composite surfaces 2 and 3-5 from a mesh using the
\inltt{extract} module:
%
\begin{lstlisting}[style=BashInputStyle]
NekMesh -m extract:surf=2,3 Mesh.xml output.xml
NekMesh -m extract:surf=2,3-5 Mesh.xml output.xml
\end{lstlisting}
%
If you also wish to have the boundaries of the extracted surface detected add the \inltt{detectbnd} option
If you also wish to have the boundaries of the extracted surface detected add
the \inltt{detectbnd} option
%
\begin{lstlisting}[style=BashInputStyle]
NekMesh -m extract:surf=2,3:detectbnd Mesh.xml output.xml
NekMesh -m extract:surf=2,3-5:detectbnd Mesh.xml output.xml
\end{lstlisting}
which will produce new composites for the extracted boundary.
\subsection{Negative Jacobian detection}
......@@ -522,24 +530,6 @@ The module parameters are:
are not self-intersecting.
\end{notebox}
\subsection{Surface extraction}
Often one wants to visualise a particular surface of a 3D mesh. \mc supports
extraction of two-dimensional surfaces which can be converted using
\inltt{XmlToVtk} or similar programs for visualisation purposes, or combined
with \inltt{FieldConvert} in order to extract the value of a 3D field on a given
surface.
To extract a surface use the command:
\begin{lstlisting}[style=BashInputStyle]
NekMesh -m extract:surf=12,3,4 volume-mesh.xml surface-mesh.xml
\end{lstlisting}
where the integers are surface IDs to be extracted.
An optional arguemnt of \inltt{detectbnd} can be added to identify the boundary composites as part of the surface extraction.
\subsection{Linearisation}
The ability to remove all the high-order information in a mesh can be useful
......
......@@ -13,6 +13,7 @@ SET(FieldUtilsHeaders
OutputModules/OutputStdOut.h
OutputModules/OutputPts.h
OutputModules/OutputXml.h
ProcessModules/ProcessAddCompositeID.h
ProcessModules/ProcessAddFld.h
ProcessModules/ProcessBoundaryExtract.h
ProcessModules/ProcessCombineAvg.h
......@@ -59,6 +60,7 @@ SET(FieldUtilsSources
OutputModules/OutputStdOut.cpp
OutputModules/OutputPts.cpp
OutputModules/OutputXml.cpp
ProcessModules/ProcessAddCompositeID.cpp
ProcessModules/ProcessAddFld.cpp
ProcessModules/ProcessBoundaryExtract.cpp
ProcessModules/ProcessCombineAvg.cpp
......
////////////////////////////////////////////////////////////////////////////////
//
// File: ProcessAddCompositeID.cpp
//
// For more information, please see: http://www.nektar.info/
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Add composite ID as a variable to the field.
//
////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
#include "ProcessAddCompositeID.h"
#include <LibUtilities/BasicUtils/ParseUtils.hpp>
#include <LibUtilities/BasicUtils/SharedArray.hpp>
namespace Nektar
{
namespace FieldUtils
{
ModuleKey ProcessAddCompositeID::className =
GetModuleFactory().RegisterCreatorFunction(
ModuleKey(eProcessModule, "addcompositeid"),
ProcessAddCompositeID::create,
"Add a field which contains the composite ID of each element");
ProcessAddCompositeID::ProcessAddCompositeID(FieldSharedPtr f)
: ProcessModule(f)
{
}
ProcessAddCompositeID::~ProcessAddCompositeID()
{
}
void ProcessAddCompositeID::Process(po::variables_map &vm)
{
if (m_f->m_verbose)
{
if (m_f->m_comm->GetRank() == 0)
{
cout << "ProcessAddCompositeID: Adding composite ID as a new field"
<< endl;
}
}
int nfields = 0;
int NumHomogeneousDir = 0;
MultiRegions::ExpListSharedPtr exp;
if (m_f->m_fielddef.size())
{
nfields = m_f->m_fielddef[0]->m_fields.size();
NumHomogeneousDir = m_f->m_fielddef[0]->m_numHomogeneousDir;
m_f->m_exp.resize(nfields + 1);
exp = m_f->AppendExpList(NumHomogeneousDir, "Composite ID");
m_f->m_exp[nfields] = exp;
}
else
{
exp = m_f->m_exp[0];
}
// Get Composites
const SpatialDomains::CompositeMap CompositeMap =
m_f->m_graph->GetComposites();
SpatialDomains::CompositeMapConstIter it;
NekDouble compid;
// loop over elements
for (int n = 0; n < exp->GetNumElmts(); ++n)
{
LocalRegions::ExpansionSharedPtr elmt = exp->GetExp(n);
// loop over composite list and search for geomtry pointer in list
for (it = CompositeMap.begin(); it != CompositeMap.end(); ++it)
{
if (find(it->second->begin(), it->second->end(), elmt->GetGeom()) !=
it->second->end())
{
compid = it->first;
break;
}
}
WARNINGL0(it != CompositeMap.end(),
"Failed to find composite ID for element: " +
boost::lexical_cast<string>(n));
// Fill element with the value of the index
int npts = elmt->GetTotPoints();
Array<OneD, NekDouble> tmp;
Vmath::Fill(npts, compid,
tmp = exp->UpdatePhys() + exp->GetPhys_Offset(n), 1);
}
// forward transform
exp->FwdTrans_IterPerExp(exp->GetPhys(), exp->UpdateCoeffs());
std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef =
m_f->m_exp[0]->GetFieldDefinitions();
std::vector<std::vector<NekDouble> > FieldData(FieldDef.size());
// copy in previous fields if they exist.
for (int i = 0; i < nfields; ++i)
{
for (int j = 0; j < FieldDef.size(); ++j)
{
FieldDef[j]->m_fields.push_back(m_f->m_fielddef[0]->m_fields[i]);
m_f->m_exp[i]->AppendFieldData(FieldDef[j], FieldData[j]);
}
}
// append composite id field
for (int j = 0; j < FieldDef.size(); ++j)
{
FieldDef[j]->m_fields.push_back("compositeID");
m_f->m_exp[nfields]->AppendFieldData(FieldDef[j], FieldData[j]);
}
m_f->m_fielddef = FieldDef;
m_f->m_data = FieldData;
}
}
}
////////////////////////////////////////////////////////////////////////////////
//
// File: ProcessAddCompositeID.h
//
// For more information, please see: http://www.nektar.info/
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Add composite ID as a variable to the field.
//
////////////////////////////////////////////////////////////////////////////////
#ifndef FIELDUTILS_PROCESSADDCOMPOSITEID
#define FIELDUTILS_PROCESSADDCOMPOSITEID
#include <FieldUtils/Module.h>
namespace Nektar
{
namespace FieldUtils
{
/**
* @brief This processing module adds a fld with the composite ID
*
*/
class ProcessAddCompositeID : public ProcessModule
{
public:
/// Creates an instance of this class
static boost::shared_ptr<Module> create(FieldSharedPtr f)
{
return MemoryManager<ProcessAddCompositeID>::AllocateSharedPtr(f);
}
static ModuleKey className;
ProcessAddCompositeID(FieldSharedPtr f);
virtual ~ProcessAddCompositeID();
/// Write mesh to output file.
virtual void Process(po::variables_map &vm);
virtual std::string GetModuleName()
{
return "ProcessAddCompositeID";
}
private:
};
}
}
#endif
......@@ -11,6 +11,7 @@ TARGET_LINK_LIBRARIES(FieldConvert FieldUtils)
ADD_NEKTAR_TEST(chan3D_tec_n10)
ADD_NEKTAR_TEST(chan3D_interppointsplane)
ADD_NEKTAR_TEST(chan3D_interppointsbox)
ADD_NEKTAR_TEST(compositeid)
ADD_NEKTAR_TEST(bfs_probe)
ADD_NEKTAR_TEST(bfs_tec)
ADD_NEKTAR_TEST(bfs_tec_rng)
......
<?xml version="1.0" encoding="utf-8" ?>
<test>
<description>Add composite ID to field</description>
<executable>FieldConvert</executable>
<parameters>-e -m addcompositeid compositeid.xml compositeid.fld</parameters>
<files>
<file description="Session File">compositeid.xml</file>
</files>
<metrics>
<metric type="L2" id="1">
<value variable="compositeID" tolerance="1e-12">2.23607</value>
</metric>
<metric type="Linf" id="2">
<value variable="compositeID" tolerance="1e-12">2</value>
</metric>
</metrics>
</test>
<?xml version="1.0" encoding="utf-8" ?>
<NEKTAR>
<GEOMETRY DIM="2" SPACE="2">
<VERTEX COMPRESSED="B64Z-LittleEndian" BITSIZE="64">eJxjYMAPGFF4H+zR5ZmwyiPUMWM1FSHPgirhgK6SFas8Qj8bijQHhn52rPII/QDohwhH</VERTEX>
<EDGE COMPRESSED="B64Z-LittleEndian" BITSIZE="64">eJxjYEAFjDhoJhw0Mw4aBljQzIHxWXHw2dD4MHvY0dTD1HGg8WHqONH4MPMAJmgAcgAA</EDGE>
<ELEMENT>
<Q COMPRESSED="B64Z-LittleEndian" BITSIZE="64">eJxjYEAFjFCaCUozo4mzQGlWKM2GQx87lOaA0pxo+gAJgAA3</Q>
</ELEMENT>
<COMPOSITE>
<C ID="0"> Q[0] </C>
<C ID="1"> Q[1] </C>
<C ID="2"> Q[2] </C>
</COMPOSITE>
<DOMAIN> C[0-2] </DOMAIN>
</GEOMETRY>
<EXPANSIONS>
<E COMPOSITE="C[0-2]" NUMMODES="3" TYPE="MODIFIED" FIELDS="u" />
</EXPANSIONS>
<CONDITIONS />
</NEKTAR>
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