Ce répertoire contient un exemple d'utilisation de fonctions C# pour le jeu de données.
Fichier CMakeLists.txt
cmake_minimum_required(VERSION 3.21 FATAL_ERROR)
project(UserFunction LANGUAGES C CXX)
add_executable(UserFunction UserFunctionModule.cc main.cc UserFunction_axl.h)
arcane_generate_axl(UserFunction)
arcane_add_arcane_libraries_to_target(UserFunction)
target_include_directories(UserFunction PUBLIC . ${CMAKE_CURRENT_BINARY_DIR})
configure_file(UserFunction.config ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
# Command to compile C# file for functions
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/ExternalFunctions.dll"
COMMAND ${ARCANE_PREFIX_DIR}/bin/arcane_dotnet_compile "${CMAKE_CURRENT_LIST_DIR}/ExternalFunctions.cs"
DEPENDS "${CMAKE_CURRENT_LIST_DIR}/ExternalFunctions.cs"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
add_custom_target(external_functions DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/ExternalFunctions.dll")
add_dependencies(UserFunction external_functions)
# Add a test to run the sample
add_test(NAME userfunction1 COMMAND ${CMAKE_CURRENT_BINARY_DIR}/UserFunction -A,UsingDotNet=1 ${CMAKE_CURRENT_LIST_DIR}/UserFunction.arc)
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Fichier ExternalFunctions.cs
using System;
using Real = System.Double;
namespace UserFunctionSample
{
public class CaseFunctions
{
public CaseFunctions()
{
m_origin =
new Real3(0.2,0.3,0.0);
}
{
Real3 delta = position - m_origin;
Real norm = 0.3 * System.Math.Sqrt(dx*dx+dy*dy+dz*dz);
Real vx = global_time * norm * dx;
Real vy = global_time * norm * dy;
Real vz = global_time * norm * dz;
return new Real3(vx,vy,vz);
}
}
}
Classe gérant un vecteur de réel de dimension 3.
double Real
Type représentant un réel.
Real y
deuxième composante du triplet
Real z
troisième composante du triplet
Real x
première composante du triplet
Fichier main.cc
#include <arcane/launcher/ArcaneLauncher.h>
int
main(int argc,char* argv[])
{
app_build_info.setCodeName("UserFunction");
}
static int run()
Point d'entrée de l'exécutable dans Arcane.
static void init(const CommandLineArguments &args)
Positionne les informations à partir des arguments de la ligne de commande et initialise le lanceur.
static ApplicationBuildInfo & applicationBuildInfo()
Informations sur les paramêtre d'exécutions de l'application.
Arguments de la ligne de commande.
Informations sur une version.
Fichier UserFunction.arc
<?xml version="1.0"?>
<case codename="UserFunction" xml:lang="en" codeversion="1.0">
<arcane>
<title>Sample</title>
<timeloop>UserFunctionLoop</timeloop>
</arcane>
<meshes>
<mesh>
<generator name="Cartesian2D" >
<nb-part-x>1</nb-part-x>
<nb-part-y>1</nb-part-y>
<origin>0.0 0.0</origin>
<x><n>20</n><length>2.0</length></x>
<y><n>20</n><length>2.0</length></y>
</generator>
</mesh>
</meshes>
<functions>
<external-assembly>
<assembly-name>ExternalFunctions.dll</assembly-name>
<class-name>UserFunctionSample.CaseFunctions</class-name>
</external-assembly>
</functions>
<arcane-post-processing>
<output-period>1</output-period>
<output>
<variable>NodeVelocity</variable>
</output>
</arcane-post-processing>
<user-function>
<node-velocity function="NodeVelocityFunc">0.0 0.0 0.0</node-velocity>
</user-function>
</case>
Fichier UserFunction.axl
<?xml version="1.0" ?>
<module name="UserFunction" version="1.0">
<description>Description of the module UserFunction</description>
<entry-points>
<entry-point method-name="compute" name="Compute" where="compute-loop" property="none" />
<entry-point method-name="startInit" name="StartInit" where="start-init" property="none" />
</entry-points>
<options>
<simple name="node-velocity" type="real3" />
</options>
<variables>
<variable name="CellCenter" field-name="cell_center" data-type="real3" dim="0" item-kind="cell" />
<variable name="NodeVelocity" field-name="node_velocity" data-type="real3" dim="0" item-kind="node" />
</variables>
</module>
Fichier UserFunction.config
<?xml version="1.0" ?>
<arcane-config code-name="UserFunction">
<time-loops>
<time-loop name="UserFunctionLoop">
<title>UserFunction</title>
<description>Default timeloop for code UserFunction</description>
<modules>
<module name="UserFunction" need="required" />
<module name="ArcanePostProcessing" need="required" />
</modules>
<entry-points where="init">
<entry-point name="UserFunction.StartInit" />
</entry-points>
<entry-points where="compute-loop">
<entry-point name="UserFunction.Compute" />
</entry-points>
</time-loop>
</time-loops>
</arcane-config>
Fichier UserFunctionModule.cc
#include <arcane/utils/Real3.h>
#include <arcane/core/ITimeLoopMng.h>
#include <arcane/core/IMesh.h>
#include <arcane/core/ICaseFunction.h>
#include <arcane/core/IStandardFunction.h>
#include "UserFunction_axl.h"
class UserFunctionModule
: public ArcaneUserFunctionObject
{
public:
: ArcaneUserFunctionObject(mbi)
{}
public:
void compute() override;
void startInit() override;
private:
};
void UserFunctionModule::
compute()
{
info() << "Module UserFunction COMPUTE";
if (m_global_iteration() > 10)
subDomain()->timeLoopMng()->stopComputeLoop(true);
Real3 cell_center = Real3::zero();
cell_center += nodes_coordinates[node];
}
m_cell_center[icell] = cell_center;
}
{
const Real current_time = m_global_time();
Real3 position = nodes_coordinates[inode];
m_node_velocity[inode] = m_node_velocity_functor->apply(current_time, position);
}
}
{
const Real current_deltat = m_global_deltat();
nodes_coordinates[inode] += m_node_velocity[inode] * current_deltat;
}
}
}
void UserFunctionModule::
startInit()
{
info() << "Module UserFunction INIT";
{
ICaseFunction* opt_function = options()->nodeVelocity.function();
if (!scf)
ARCANE_FATAL(
"No standard case function for option 'node-velocity'");
auto* functor = scf->getFunctorRealReal3ToReal3();
if (!functor)
ARCANE_FATAL(
"Standard function '{0}' is not convertible to f(Real,Real3) -> Real3", opt_function->
name());
m_node_velocity_functor = functor;
}
}
ARCANE_REGISTER_MODULE_USERFUNCTION(UserFunctionModule);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Interface d'une fonction mathématique binaire.
virtual String name() const =0
nom de la fonction
Interface gérant une fonction standard.
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Int32 nbNode() const
Nombre de noeuds de l'entité
Informations pour construire un module.
constexpr __host__ __device__ Real3 & assign(Real ax, Real ay, Real az)
Affecte à l'instance le triplet (ax,ay,az)
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.