Conjugate heat transfer of simple geometries - comparison with exp data

Questions and remarks about code_saturne usage
Forum rules
Please read the forum usage recommendations before posting.
Yvan Fournier
Posts: 4080
Joined: Mon Feb 20, 2012 3:25 pm

Re: Conjugate heat transfer of simple geometries - comparison with exp data

Post by Yvan Fournier »

Hello,

The cs_user_zones function allows defining zones, but for most cases (i.e. classical selection criteria) you can simply use the GUI.

In your example, you need to replace:

Code: Select all

 for (int ii = 0 ; ii < n_cells ; ii++)
    temptot += temp->val[ii]*cell_vol[ii]
;

With something similar to:

Code: Select all

const cs_zone_t *z = cs_volume_zone_by_name("solid");

 for (cs_lnum_t idx = 0 ; idx < z->n_elts; ii++) {
  cs_lnum_t  ii = z->elt_ids[idx];
  temptot += temp->val[ii]*cell_f_vol[ii];
}
So as to sum values only in the solid zone (adjust the name for your case: it might be different from "solid").
For cell weights, you can use cell_f_vol or cell_vol interchangeably if there is no porosity, otherwise cell_f_vol is more general.
For the matching denominator, use z->measure for the zone's volume (in place of voltot for the whole mesh).
For parallelism, be careful: you need to call cs_parall_sum as in the example for the numerator, but not for z->measure, as it already contains the summed (global) value.

Best regards,

Yvan
jgd23
Posts: 141
Joined: Mon Jun 06, 2016 10:00 am

Re: Conjugate heat transfer of simple geometries - comparison with exp data

Post by jgd23 »

Hello Yvan,

Thank you for your answer.

I modify my file. I have a lot of warnings.
First I try to make it works in serial.

There is the modified code

Code: Select all

/*============================================================================
 * This function is called at the end of each time step, and has a very
 *  general purpose
 *  (i.e. anything that does not have another dedicated user function)
 *============================================================================*/

/* VERS */

/*
  This file is part of code_saturne, a general-purpose CFD tool.

  Copyright (C) 1998-2022 EDF S.A.

  This program is free software; you can redistribute it and/or modify it under
  the terms of the GNU General Public License as published by the Free Software
  Foundation; either version 2 of the License, or (at your option) any later
  version.

  This program 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 General Public License for more
  details.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
  Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

/*----------------------------------------------------------------------------*/

#include "cs_defs.h"

/*----------------------------------------------------------------------------
 * Standard C library headers
 *----------------------------------------------------------------------------*/

#include <assert.h>
#include <math.h>

#if defined(HAVE_MPI)
#include <mpi.h>
#endif

/*----------------------------------------------------------------------------
 * PLE library headers
 *----------------------------------------------------------------------------*/

#include <ple_coupling.h>

/*----------------------------------------------------------------------------
 * Local headers
 *----------------------------------------------------------------------------*/

#include "cs_headers.h"

/*----------------------------------------------------------------------------*/

BEGIN_C_DECLS

/*----------------------------------------------------------------------------*/
/*!
 * \file cs_user_extra_operations.c
 *
 * \brief This function is called at the end of each time step, and has a very
 * general purpose (i.e. anything that does not have another dedicated
 * user function)
 */
/*----------------------------------------------------------------------------*/

/*============================================================================
 * User function definitions
 *============================================================================*/

/*----------------------------------------------------------------------------*/
/*!
 * \brief This function is called at the end of each time step.
 *
 * It has a very general purpose, although it is recommended to handle
 * mainly postprocessing or data-extraction type operations.
 *
 * \param[in, out]  domain   pointer to a cs_domain_t structure
 */
/*----------------------------------------------------------------------------*/

void
cs_user_extra_operations(cs_domain_t     *domain)
{
  /* Variables declaration */

  /* Handle to the moy.dat file that will be filled with Tav;
   declared as static so as to keep its value between calls. */
  static FILE *file = NULL;

  /* Get pointers to the mesh and mesh quantities structures */
  const cs_mesh_t *m= cs_glob_mesh;
  const cs_mesh_quantities_t *fvq = cs_glob_mesh_quantities;

  /* Number of cells */
  const int n_cells = m->n_cells;

  /* Cell volumes */
  const cs_real_t *cell_vol = fvq->cell_vol;

  /* Get the temperature field */
  const cs_field_t *temp = cs_field_by_name_try("temperature");

  /* Total domain volume */
  cs_real_t voltot = fvq->tot_vol;

  /* Temp * volumes sum and Tavg */
  cs_real_t temptot =0., Tavg =0.;

  /* Compute the sum T*vol */
 /*for (int ii = 0 ; ii < n_cells ; ii++)*/
 /*temptot += temp->val[ii]*cell_vol[ii];*/
  
 const cs_zone_t *z = cs_volume_zone_by_name("solid");

 for (cs_lnum_t idx = 0 ; idx < z->n_elts; ii++) 
 {
  cs_lnum_t  ii = z->elt_ids[idx];
  temptot += temp->val[ii]*cell_vol[ii];
  }

  /* Parallel sums */
  cs_parall_sum(1, CS_REAL_TYPE, &temptot);

  /* Compute Tavg */
  /*Tavg = temptot / voltot;*/
  Tavg = temptot / z;

  /* Open the file moy.dat at the first iteration*/
  /*   and write the first comment line only on the*/
  /*   first processor (0 in parallel, -1 in serial) */
  /*if (cs_glob_time_step->nt_cur == 1 && cs_glob_rank_id <= 0) {*/
  /*  file = fopen("moy.dat", "a");*/
  /*  fprintf(file, "#Time (s)   Average Temperature (C) \n");*/
  }

/* Print the average temperature at the current time step*/
/*   on the first processor only */
 /* if (cs_glob_rank_id <= 0)*/
  /*   fprintf(file, "%.6f  %.6f\n",cs_glob_time_step->t_cur, Tavg);*/

/* Close the file moy.dat at the last iteration*/
/*   on the first processor only */
/*  if (cs_glob_time_step->nt_cur == cs_glob_time_step->nt_max*/
 /*  && cs_glob_rank_id <= 0)*/
 /*   fclose(file);*/
}

/*----------------------------------------------------------------------------*/

END_C_DECLS
This is the warning:

Code: Select all

/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c: In function ‘cs_user_extra_operations’:
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:119:44: error: ‘ii’ undeclared (first use in this function)
  119 |  for (cs_lnum_t idx = 0 ; idx < z->n_elts; ii++)
      |                                            ^~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:119:44: note: each undeclared identifier is reported only once for each function it appears in
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:121:14: warning: declaration of ‘ii’ shadows previous non-variable [-Wshadow]
  121 |   cs_lnum_t  ii = z->elt_ids[idx];
      |              ^~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:130:18: error: invalid operands to binary / (have ‘cs_real_t’ {aka ‘double’} and ‘const cs_zone_t *’)
  130 |   Tavg = temptot / z;
      |                  ^
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:111:26: warning: variable ‘Tavg’ set but not used [-Wunused-but-set-variable]
  111 |   cs_real_t temptot =0., Tavg =0.;
      |                          ^~~~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:108:13: warning: unused variable ‘voltot’ [-Wunused-variable]
  108 |   cs_real_t voltot = fvq->tot_vol;
      |             ^~~~~~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:99:13: warning: unused variable ‘n_cells’ [-Wunused-variable]
   99 |   const int n_cells = m->n_cells;
      |             ^~~~~~~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:92:16: warning: unused variable ‘file’ [-Wunused-variable]
   92 |   static FILE *file = NULL;
      |                ^~~~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:86:43: warning: unused parameter ‘domain’ [-Wunused-parameter]
   86 | cs_user_extra_operations(cs_domain_t     *domain)
      |                          ~~~~~~~~~~~~~~~~~^~~~~~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c: At top level:
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:150:1: error: expected identifier or ‘(’ before ‘}’ token
  150 | }
      | ^
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:92:16: warning: ‘file’ defined but not used [-Wunused-variable]
   92 |   static FILE *file = NULL;
      |                ^~~~
ii was used before without declaration and without problem...

Best regards
Yvan Fournier
Posts: 4080
Joined: Mon Feb 20, 2012 3:25 pm

Re: Conjugate heat transfer of simple geometries - comparison with exp data

Post by Yvan Fournier »

Hello,

Sorry, there is a typo in my code:

Replace:

Code: Select all

 for (cs_lnum_t idx = 0 ; idx < z->n_elts; ii++) 
with:

Code: Select all

for (cs_lnum_t idx = 0 ; idx < z->n_elts; idx++) 
Best regards,

Yvan
jgd23
Posts: 141
Joined: Mon Jun 06, 2016 10:00 am

Re: Conjugate heat transfer of simple geometries - comparison with exp data

Post by jgd23 »

Hello,

One error remains.

Code: Select all

/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:130:18: error: invalid operands to binary / (have ‘cs_real_t’ {aka ‘double’} and ‘const cs_zone_t *’)
  130 |   Tavg = temptot / z;
      |                  ^
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:111:26: warning: variable ‘Tavg’ set but not used [-Wunused-but-set-variable]
  111 |   cs_real_t temptot =0., Tavg =0.;
      |                          ^~~~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:108:13: warning: unused variable ‘voltot’ [-Wunused-variable]
  108 |   cs_real_t voltot = fvq->tot_vol;
      |             ^~~~~~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:99:13: warning: unused variable ‘n_cells’ [-Wunused-variable]
   99 |   const int n_cells = m->n_cells;
      |             ^~~~~~~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:92:16: warning: unused variable ‘file’ [-Wunused-variable]
   92 |   static FILE *file = NULL;
      |                ^~~~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:86:43: warning: unused parameter ‘domain’ [-Wunused-parameter]
   86 | cs_user_extra_operations(cs_domain_t     *domain)
      |                          ~~~~~~~~~~~~~~~~~^~~~~~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c: At top level:
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:92:16: warning: ‘file’ defined but not used [-Wunused-variable]
   92 |   static FILE *file = NULL;
      |                ^~~~
How to declare correctly the division by "z"?

Best regards
Antech
Posts: 197
Joined: Wed Jun 10, 2015 10:02 am

Re: Conjugate heat transfer of simple geometries - comparison with exp data

Post by Antech »

Hello.
If you mean z-coordinate, you can do the following:

Code: Select all

const cs_real_3_t *restrict cellCoord=(const cs_real_3_t *restrict)cs_glob_mesh_quantities->cell_cen;
cs_real_t coord_z=(double)cellCoord[iCell][2];
Here iCell is the cell index. It's adapted code from my heat exchanger "plugin" so should work.

If you need cell volume (in your code z is a volume zone structure) you may sum over cells:

Code: Select all

const cs_real_t *cellVlm=domain->mesh_quantities->cell_vol;
Then sum current thread (cellVlm[iCell]) and use cs_parall_sum, as usual to ensure you always will get full volume for all threads.

If you need particular zone, not all cells of current thread, loop over this zone's cells:

Code: Select all

cs_lnum_t iZoneCell,iCell;
const cs_zone_t *zone=cs_volume_zone_by_name_try("ZoneName");
cs_real_t vlmSum=0;
for (iZoneCell=0;iZoneCell<zone->n_elts;iZoneCell++) /* Zone cell loop */
{
  iCell=zone->elt_ids[iZoneCell]; /* Cell index in current thread by index in particular zone */
 /* Here use iCell as cell index, for example: */
 vlmSum=vlmSum+cellVlm[iCell]; /* Zone volume */
};
cs_parall_sum(1,CS_REAL_TYPE,&vlmSum); /* Zone volume for all threads */
jgd23
Posts: 141
Joined: Mon Jun 06, 2016 10:00 am

Re: Conjugate heat transfer of simple geometries - comparison with exp data

Post by jgd23 »

Hello Antech,

Yes in my case z is related to volume of the "solid" zone

I don't understand where is the link between z defined below

Code: Select all

const cs_zone_t *z = cs_volume_zone_by_name("solid");

 for (cs_lnum_t idx = 0 ; idx < z->n_elts; ii++) 
 {
  cs_lnum_t  ii = z->elt_ids[idx];
  temptot += temp->val[ii]*cell_vol[ii];
  }
and your line with cellVlm?

Code: Select all

const cs_real_t *cellVlm=domain->mesh_quantities->cell_vol;
For the average temperature I need to divide
Tavg = temptot / z

I am sorry for the basic question, C programation is quite obscur for me.

Best regards
Antech
Posts: 197
Joined: Wed Jun 10, 2015 10:02 am

Re: Conjugate heat transfer of simple geometries - comparison with exp data

Post by Antech »

Sorry, my first example is more abstract, for all cells of current thread or for entire domain if used with cs_parall_sum (second fragment is for particular zone). I hope the following will give you summary volume of "solid" zone and volume-ave temperature in units used by the solver (Celsius or Kelvin).

Code: Select all

cs_lnum_t iZoneCell,iCell;
cs_real_t zoneVlmSum,zoneTempSum,zoneTempAve;
/* Pointers required for calculation */
const cs_real_t *cellTemp=(const cs_real_t*)CS_F_(t)->val; /* Temperature array in current thread cells */
const cs_zone_t *zone=cs_volume_zone_by_name_try("solid"); /* Zone structure (for current thread) */
/* Get summary volume or any other zone cell statistic */
zoneVlmSum=0; /* Init volume */
zoneTempSum=0; /* Init Volume*Temp sum */
for (iZoneCell=0;iZoneCell<zone->n_elts;iZoneCell++) /* Zone cell loop */
{
  iCell=zone->elt_ids[iZoneCell]; /* Cell index in current thread by index in selected zone */
  zoneVlmSum=zoneVlmSum+cellVlm[iCell]; /* Zone volume sum */
  zoneTempSum=zoneTempSum+cellTemp[iCell]*cellVlm[iCell]; /* Zone volume*temp sum */
};
cs_parall_sum(1,CS_REAL_TYPE,&zoneVlmSum); /* Zone volume for all threads */
cs_parall_sum(1,CS_REAL_TYPE,&zoneTempSum); /* Zone volume*temp sum volume for all threads */
zoneTempAve=zoneTempSum/zoneVlmSum; /* Volume-ave temperature in zone */
/* That's it, you can use zoneTempAve variable, don't forget to check units... */
I didn't check so you will probably need to debug but then it should work (I use such approach in my different "plugins" for Saturne).
Here we get temperature field for all thread cells and zone params structure. But, because we cycle through zone cells only, we get only zone statistics or other processing, not for all thread cells. There is zone->elt_ids[iZoneCell] array in zone structure that gives cell indices in current thread that are related to selected zone (if we just use iZoneCell counter we will get wrong cells).
I suggest to introduce function that gives non-zero or positive value and use it in divisor to avoid division by zero even if zone is void for some reason. Also, in practise it's very useful to check pointers to zones or fields and bft_printf() errors if any - it simplifies case debugging.
Oops, there was an error, corrected.
jgd23
Posts: 141
Joined: Mon Jun 06, 2016 10:00 am

Re: Conjugate heat transfer of simple geometries - comparison with exp data

Post by jgd23 »

Hello Antech,

Thank you for your help. I think it is really close to work.
The compiler complains about

Code: Select all

/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:104:25: error: ‘cellVlm’ undeclared (first use in this function)
  104 |   zoneVlmSum=zoneVlmSum+cellVlm[iCell]; /* Zone volume sum */
      |                         ^~~~~~~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:104:25: note: each undeclared identifier is reported only once for each function it appears in
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:89:34: warning: variable ‘zoneTempAve’ set but not used [-Wunused-but-set-variable]
   89 | cs_real_t zoneVlmSum,zoneTempSum,zoneTempAve;
      |                                  ^~~~~~~~~~~
/home/julien/Travail/test_cyl4/SRC/cs_user_extra_operations.c:86:43: warning: unused parameter ‘domain’ [-Wunused-parameter]
   86 | cs_user_extra_operations(cs_domain_t     *domain)
If I define it in cs_real_t it gives me new errors...

Best regards
Antech
Posts: 197
Joined: Wed Jun 10, 2015 10:02 am

Re: Conjugate heat transfer of simple geometries - comparison with exp data

Post by Antech »

Add this in pointers section:

Code: Select all

const cs_real_t *cellVlm=domain->mesh_quantities->cell_vol; /* Pointer to cell volume array [m3] */
jgd23
Posts: 141
Joined: Mon Jun 06, 2016 10:00 am

Re: Conjugate heat transfer of simple geometries - comparison with exp data

Post by jgd23 »

Yes it is good now, no more error during compilation!

I don't know how to extract the value now. I try also fprint but everything returns errors...

Code: Select all

    cs_post_write_var(mesh_id,
                      CS_POST_WRITER_ALL_ASSOCIATED,  /* writer id filter */
                      "zoneTempAve",             /* var_name */
                      1,                              /* var_dim */
                      true,                           /* interlace, */
                      false,                          /* use_parent */
                      CS_POST_TYPE_cs_real_t,         /* var_type */
                      NULL,                           /* cel_vals */
                      s_i_faces,                      /* i_face_vals */
                      s_b_faces,                      /* b_face_vals */
                      ts);
Best regards
Post Reply