Posted Tue, 15 Apr 2014 18:35:43 GMT by Ludwig Ehlert
Hello Forum,

i would like here to continue on my initial topic of coupling Pest manually with Feflow in case the parameter which need to be calibrated are not available in the current FePest version.

After helpful contributions by Carlos and Giovanni it turned out that a Plugin development would be taking less time than the setup of all the Pest files.
The state is that the function of this Plugin is not entirely clear to me. Until now i assume the following way of functionality:

1. In FePest a #IFM implemented# parameter is assigned and during the run of the check function a additional template file (ifm.tpl) is added to the Pest directory.
2. The plugin in Feflow is triggered before every simulation run. This is done by the callback function PreFlowSimulation.
3. The plugin assignes the in the template file stored, estimated parameters (in my case Van Genuchten alpha and n, and the saturation limits s_s and s_r)
4. After every model call by FePest the parameter is changed for optimization in the ifm.tpl file and Feflow assignes the changed parameters in the .fem file.

I hope this gives a sufficient summary of the development so far and i hope it is right so far.

Regards
Ludwig
Posted Wed, 16 Apr 2014 09:33:32 GMT by Carlos Andres Rivera Villarreyes Global Product Specialist - FEFLOW
Dear Ludwig,

Some thoughts to complement discussion...

First a general overview, PEST creates kind of copies of both material files (FPI) and observation files (FPO) in a generalized manner. For example, a typical template file (TPF) will look like this:

      [color=blue]ptf %
      xxp %xxp%[/color]

where [b]xxp [/b]is a variable (material property) in FEFLOW. Every optimization iteration in a PEST run, a number is assigned to section between %...%. FePEST takes this file and connect it with the material file (FPI) in order to run a new scenario. Analogy it happens for IFM-implemented observations (see previous posts).

When you define an IFM-Implemented parameter in FePEST (additional to the “normal” parameter definition), FePEST creates a so-called ifm.tpl, which is linked to ifm.fpi.

Basically the IFM plugin should carry out the following:

1) Read material properties from an existing FPI file, for example

        [color=blue]xxp 0.75[/color]

2) Assign corresponding material values to an specific FEFLOW variable

Notice that if problem contains time-varying materials, you should indicate when material assignment has exactly to occur. The IFM plug-in should complete all assignments before FEM file runs, i.e. callback PreSimulation.

With all material assigned, FEFLOW will run normally and observation points will be created. FePEST will create the result FPO file (s). PEST will read these observations, compute objective function and create a new parameter FPI file. Now the IFM plug-in has the information to read and assign new material properties in next FEFLOW run.

Cheers,

Carlos
Posted Thu, 17 Apr 2014 12:30:24 GMT by Ludwig Ehlert
Hello Carlos,

i managed to develop the plugin so far (Code coming soon). The problem which remains is that the callback functions are not triggered when PEST is starting the .fem file.
I tried so far:

PreSimulation
PreEnterSimulation
PreFlowSimulation
PostLoadDocument

Is there anything else beside the Callback function, the attaching of the plugin and the activation i have to do so the plugin starts when FePest is using the .fem file?

Thanks
Ludwig
Posted Tue, 22 Apr 2014 08:28:19 GMT by Ludwig Ehlert
Hello Carlos,

here the code of the plugin. The code is placed in the callback section of the IFM structure.

#include "stdifm.h"
#include "IFM Plug-in1.h"
#include <ifm/document.h>
#include <fstream>
#include <iostream>
#include <string>

using namespace std;

IfmModule g_pMod;  /* Global handle related to this plugin */

#pragma region IFM_Definitions
/* --- IFMREG_BEGIN --- */
/*  -- Do not edit! --  */

static void PreEnterSimulator (IfmDocument);

/*
* Enter a short description between the quotation marks in the following lines:
*/
static const char szDesc[] =
  "Please, insert a plug-in description here!";

#ifdef __cplusplus
extern "C"
#endif /* __cplusplus */

IfmResult RegisterModule(IfmModule pMod)
{
  if (IfmGetFeflowVersion (pMod) < IFM_REQUIRED_VERSION)
    return False;
  g_pMod = pMod;
  IfmRegisterModule (pMod, "SIMULATION", "IFM_PLUG_IN1", "IFM Plug-in1", 0x1000);
  IfmSetDescriptionString (pMod, szDesc);
  IfmSetCopyrightPath (pMod, "IFM Plug-in1.txt");
  IfmSetHtmlPage (pMod, "IFM Plug-in1.htm");
  IfmSetPrimarySource (pMod, "IFM Plug-in1.cpp");
  IfmRegisterProc (pMod, "PreEnterSimulator", 1, (IfmProc)PreEnterSimulator);
  return True;
}

static void PreEnterSimulator (IfmDocument pDoc)
{
  CIfmPlugIn1::FromHandle(pDoc)->PreEnterSimulator (pDoc);
}

/* --- IFMREG_END --- */
#pragma endregion


///////////////////////////////////////////////////////////////////////////
// Implementation of CIfmPlugIn1

// Constructor
CIfmPlugIn1::CIfmPlugIn1 (IfmDocument pDoc)
  : m_pDoc(pDoc)
{
  /*
  * TODO: Add your own code here ...
  */
}

// Destructor
CIfmPlugIn1::~CIfmPlugIn1 ()
{
  /*
  * TODO: Add your own code here ...
  */
}

// Obtaining class instance from document handle
CIfmPlugIn1* CIfmPlugIn1::FromHandle (IfmDocument pDoc)
{
  return reinterpret_cast<CIfmPlugIn1*>(IfmDocumentGetUserData(pDoc));
}

// Callbacks
void CIfmPlugIn1::PreEnterSimulator (IfmDocument pDoc)
// Reading number of Elements
{ int maxElement = IfmGetNumberOfElements(pDoc);
//Reading the values
double tab [5]={ 0.000, 0.000, 0.000, 0.000};
string colA;
double colB;

int i=0;
ifstream inputFile("C:\\PEST\\Basis_225_181_2L_simple_unsat_cal\\ifm.fpi");
if (inputFile.is_open())
{
while ((!inputFile.eof())&&(i<5))
{

inputFile>>colA;
inputFile>>colB;
tab[i]=colB;
i++;
}
inputFile.close();
}
double Value_s_s=tab [0];
double Value_s_r=tab [1];
double Value_alpha=tab [2];
double Value_n=tab [3];
//Writing values to file
ofstream myfile;
  myfile.open ("C:\\PEST\\Basis_225_181_2L_simple_unsat_cal\\example.txt");
  myfile << tab[0] << tab[1] << tab[2] << tab[3];
  myfile.close();
//Assigning the values
for (int nElement=0;nElement < maxElement;nElement++)
{
IfmSetMatUnsatFittingCoefficient(pDoc,nElement,Value_alpha);
IfmSetMatUnsatFittingExponent(pDoc,nElement,Value_n);
IfmSetMatUnsatMaximumSaturation(pDoc,nElement,Value_s_s);
IfmSetMatUnsatResidualSaturation(pDoc,nElement,Value_s_r);
}
}


//Ludwig
Posted Tue, 22 Apr 2014 12:43:06 GMT by Ludwig Ehlert
Hello Forum,

the code i posted is finally working. The problem which caused the error was finally much simpler. My FePest project was connected to another .fem file and also didn't have the plugin attached.

With the right .fem the callback structure works fine and in combination with the PARDISO solver it is also acceptable fast.

Best regards
Ludwig
Posted Tue, 22 Apr 2014 13:35:52 GMT by Carlos Andres Rivera Villarreyes Global Product Specialist - FEFLOW
Hello Ludwig,

Good to hear that you could succeed!
As an additional tip, if you have want to take all advantages of FePEST parallelization capabilities, your IFM plug-in should be able to read/write in the current  FePEST working directory (e.g. in external slaves). This information can be retrieved with an environmental variable.

Cheers,

Carlos

You must be signed in to post in this forum.