[petsc-users] Problems with PetscFECreateLagrange(PETSC_COMM_WORLD, 3, 1, PETSC_TRUE, 2, 3, or 4, PETSC_DETERMINE, &fe_u)

Matthew Knepley knepley at gmail.com
Sat Jun 27 19:38:39 CDT 2026


On Sat, Jun 27, 2026 at 7:50 PM Rafel Amer Ramon via petsc-users <
petsc-users at mcs.anl.gov> wrote:

>
> Dear Jed,
>
> if a run
>
> mpirun -np 32 --hostfile ~/hosts ./ex06 -mesh_input torus.msh -lua_input function2.lua -order 1 -snes_type ksponly -ksp_type gmres -pc_type gamg -snes_view_solution vtk:solution.vtu
> ===========================================================
>  PARALLEL RESOLUTION OF THE TORUS EQUATION SUCCESSFUL
>  Total degrees of freedom in the mesh: 24272
>  Solver convergence reason (Reason ID): 5
>  Iterations performed: 1
> ===========================================================
> mce at mce-eseiaat:~/Programming/C/PETSc/petsc08$ ls -lh solution.vtu
> -rw-r--r-- 1 mce mce 5.7M Jun 28 01:44 solution.vtu
>
>
>
> and
>
> mpirun -np 32 --hostfile ~/hosts ./ex06 -mesh_input torus.msh -lua_input function2.lua -order 2 -snes_type ksponly -ksp_type gmres -pc_type gamg -snes_view_solution vtk:solution.vtu
> ===========================================================
>  PARALLEL RESOLUTION OF THE TORUS EQUATION SUCCESSFUL
>  Total degrees of freedom in the mesh: 220123
>  Solver convergence reason (Reason ID): 5
>  Iterations performed: 1
> ===========================================================
> mce at mce-eseiaat:~/Programming/C/PETSc/petsc08$ ls -lh solution.vtu
> -rw-r--r-- 1 mce mce 5.7M Jun 28 01:46 solution.vtu
>
>
> In the first case
>
> Total degrees of freedom in the mesh: 24272
>
> and in the second
>
> Total degrees of freedom in the mesh: 220123
>
> I thougth that if the number of degrees of freedom are diffrent, the size
> of the file solution.vtu
> also must be different.
>

Nope! Visualization people refuse to learn about discretizations. It is
their biggest collective failing. There is some stuff for higher order in
VTK but it is complete crap. I put it in for PyVista, which is easier to
work with, and it is still bad because it assumes equispaced points, which
is unstable. I cannot say enough about the utter idiocy of higher order
visualization.

  Thanks,

      Matt


> Best regards,
>
> Rafel Amer
>
> El 28/6/26 a les 1:28, Jed Brown ha escrit:
>
> What do you mean by "with all the data obtained by the solver"?
>
> One does not need any code to use this runtime option: -snes_view_solution vtk:solution.vtu
>
> Are you wanting to store the sort of output you get from -snes_view into a file?
>
> Rafel Amer Ramon via petsc-users <petsc-users at mcs.anl.gov> <petsc-users at mcs.anl.gov> writes:
>
>
> Hi,
>
> I have a program ex06.c (I attach it) that uses PETSc and
>
> PetscFECreateLagrange(PETSC_COMM_WORLD, 3, 1, PETSC_TRUE, 2, 3, or 4, PETSC_DETERMINE, &fe_u)
>
> When I save the solution to a file solucio_torus.vtu with the code
>
>     PetscViewer viewer_vtu;
>     PetscSection section;
>
>     ierr = PetscViewerCreate(PETSC_COMM_WORLD, &viewer_vtu); CHKERRQ(ierr);
>     ierr = PetscViewerSetType(viewer_vtu, PETSCVIEWERVTK); CHKERRQ(ierr);
>
>     ierr = PetscViewerFileSetMode(viewer_vtu, FILE_MODE_WRITE); CHKERRQ(ierr);
>     ierr = PetscViewerFileSetName(viewer_vtu, "solucio_torus.vtu"); CHKERRQ(ierr);
>
>     ierr = DMGetLocalSection(dm, &section); CHKERRQ(ierr);
>     if (section)
>         ierr = PetscSectionSetFieldName(section, 0, "Solucio"); CHKERRQ(ierr);
>
>     ierr = PetscObjectSetName((PetscObject)u_solucio, ""); CHKERRQ(ierr);
>     ierr = VecView(u_solucio, viewer_vtu); CHKERRQ(ierr);
>     ierr = PetscViewerDestroy(&viewer_vtu); CHKERRQ(ierr);
>
> it always generate a file solucio_torus.vtu of 4.5MB independently of the degree of the Lagrange polynomials, 2, 3 or 4.
> I run the code
>
> mpirun -np 32 --hostfile ~/hosts ./ex08 -mesh_input torus.msh -lua_input function2.lua -order 3 -snes_type ksponly -ksp_type gmres -pc_type gamg
>
> Does anybody knows how to save a file solucio_torus.vtu
> with all the data obtained by the solver
>  ierr = SNESSolve(snes, NULL, u_solucio); CHKERRQ(ierr);
> Thank you very much.
>
> Best regards,
>
> Rafel Amer
> /**************************************************************************************
> * Filename:   ex04.c
> * Author:     Rafel Amer (rafel.amer AT upc.edu)
> * Copyright:  Rafel Amer 2026
> * Disclaimer: This code is presented "as is" and it has been written for
> * educational purposes.
> *
> * License:    This library  is free software; you can redistribute it and/or
> * modify it under the terms of either:
> *
> * 1 the GNU Lesser General Public License as published by the Free
> * Software Foundation; either version 3 of the License, or (at your
> * option) any later version.
> *
> * or
> *
> * 2 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.
> *
> *	      See https://urldefense.us/v3/__https://www.gnu.org/licenses/__;!!G_uCfscf7eWS!ZF-nNJ74-l_81-p_aqRGdF80LcRs5UL2FUZQhP9G6s00w8eb4aEoXR6uR6fCmGTUF40LQn5VCbgi78CC5LCp$  <https://urldefense.us/v3/__https://www.gnu.org/licenses/__;!!G_uCfscf7eWS!Zbl201-N3E8DVOcdhVFdJlbiUzCZWue6mV2jeUg3l-z-b7oxVjFYdAdYS-YPG_7NBFe9AW8zHw9tVa6HVZjrwTSsYg$>
> ***************************************************************************************/
> #include <petscdmplex.h>
> #include <petscsys.h>
> #include <petscds.h>
> #include <petscfe.h>
> #include <petscsnes.h> // Canviem a la llibreria SNES per a la gestió correcta de memòria
> #include <petscviewerhdf5.h>
> #include <lua.h>
> #include <lualib.h>
> #include <lauxlib.h>
>
> static char help[] = "Solucionador del tòrus via SNES (ksponly) per a elements finits en paral·lel.\n\n";
>
> static PetscErrorCode CondicioContornDirichlet(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
> {
>     // u[0] = 0.0;
>     u[0] = 100*x[2];
>     return 0;
> }
>
> static void f0_volum(PetscInt dim, PetscInt Nf, PetscInt NfAux,
>                      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
>                      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
>                      PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
> {
>     PetscScalar c = (a && NfAux > 0 && aOff) ? a[aOff[0] + 4] : 0.0;
>     PetscScalar f = (a && NfAux > 0 && aOff) ? a[aOff[0] + 5] : 0.0;
>     f0[0] = c * u[0] - f;
> }
>
> static void f1_volum(PetscInt dim, PetscInt Nf, PetscInt NfAux,
>                      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
>                      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
>                      PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[])
> {
>     PetscScalar coef_a = (a && NfAux > 0 && aOff) ? a[aOff[0] + 0] : 1.0;
>     PetscScalar b1     = (a && NfAux > 0 && aOff) ? a[aOff[0] + 1] : 0.0;
>     PetscScalar b2     = (a && NfAux > 0 && aOff) ? a[aOff[0] + 2] : 0.0;
>     PetscScalar b3     = (a && NfAux > 0 && aOff) ? a[aOff[0] + 3] : 0.0;
>
>     f1[0] = coef_a * u_x[0] + b1 * u[0];
>     f1[1] = coef_a * u_x[1] + b2 * u[0];
>     f1[2] = coef_a * u_x[2] + b3 * u[0];
> }
>
> static void g3_jacobia(PetscInt dim, PetscInt Nf, PetscInt NfAux,
>                        const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
>                        const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
>                        PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])
> {
>     PetscScalar coef_a = (a && NfAux > 0 && aOff) ? a[aOff[0] + 0] : 1.0;
>     g3[0] = coef_a; g3[1] = 0.0;    g3[2] = 0.0;
>     g3[3] = 0.0;    g3[4] = coef_a; g3[5] = 0.0;
>     g3[6] = 0.0;    g3[7] = 0.0;    g3[8] = coef_a;
> }
>
> static PetscErrorCode EvaluaCoeficientsLua(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
> {
>     lua_State *L = (lua_State *)ctx;
>     lua_getglobal(L, "fem");
>     lua_pushnumber(L, x[0]);
>     lua_pushnumber(L, x[1]);
>     lua_pushnumber(L, x[2]);
>     if (lua_pcall(L, 3, 1, 0) != LUA_OK) return PETSC_ERR_USER;
>
>     lua_getfield(L, -1, "a");  u[0] = lua_tonumber(L, -1); lua_pop(L, 1);
>     lua_getfield(L, -1, "b1"); u[1] = lua_tonumber(L, -1); lua_pop(L, 1);
>     lua_getfield(L, -1, "b2"); u[2] = lua_tonumber(L, -1); lua_pop(L, 1);
>     lua_getfield(L, -1, "b3"); u[3] = lua_tonumber(L, -1); lua_pop(L, 1);
>     lua_getfield(L, -1, "c");  u[4] = lua_tonumber(L, -1); lua_pop(L, 1);
>     lua_getfield(L, -1, "f");  u[5] = lua_tonumber(L, -1); lua_pop(L, 1);
>     lua_pop(L, 1);
>     return 0;
> }
>
> int main(int argc, char **argv)
> {
>     DM             dm, dmDist = NULL;
>     PetscErrorCode ierr;
>     PetscMPIInt    rank, size;
>     PetscBool      flg;
>     lua_State      *L;
>     PetscInt       ordre_element = 4;
>     char           filename[PETSC_MAX_PATH_LEN] = "torus.msh";
>     char           luafilename[PETSC_MAX_PATH_LEN] = "function.lua";
>
>     ierr = PetscInitialize(&argc, &argv, (char*)0, help); if (ierr) return ierr;
>     ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
>     ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size); CHKERRQ(ierr);
>
>     ierr = PetscOptionsGetString(NULL, NULL, "-mesh_input", filename, sizeof(filename), &flg); CHKERRQ(ierr);
>     ierr = PetscOptionsGetString(NULL, NULL, "-lua_input", luafilename, sizeof(luafilename), &flg); CHKERRQ(ierr);
>     ierr = PetscOptionsGetInt(NULL, NULL, "-order", &ordre_element, &flg); CHKERRQ(ierr);
>
>     // [Pas 1] Llegir i distribuir la malla
>     ierr = DMPlexCreateGmshFromFile(PETSC_COMM_WORLD, filename, PETSC_TRUE, &dm); CHKERRQ(ierr);
>     ierr = DMSetFromOptions(dm); CHKERRQ(ierr);
>
>     // Forcem a PETSc a incloure les etiquetes de Gmsh durant la distribució paral·lela
>     ierr = DMPlexDistribute(dm, 0, NULL, &dmDist);
>     CHKERRQ(ierr);
>     if (dmDist)
>     {
>         ierr = DMDestroy(&dm); CHKERRQ(ierr);
>         dm = dmDist;
>     }
>
>     // [Pas 2] Carregar Lua de forma aïllada
>     if ((L = luaL_newstate()) == NULL) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_MEM, "Error creant Lua.");
>     luaL_openlibs(L);
>     if (luaL_dofile(L, luafilename) != LUA_OK) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Error carregant function.lua");
>
>     // [Pas 3] Configurar l'espai discret principal (u)
>     PetscFE fe_u;
>     ierr = PetscFECreateLagrange(PETSC_COMM_WORLD, 3, 1, PETSC_TRUE, ordre_element, PETSC_DETERMINE, &fe_u); CHKERRQ(ierr);
>     ierr = DMSetField(dm, 0, NULL, (PetscObject)fe_u); CHKERRQ(ierr);
>     ierr = DMCreateDS(dm); CHKERRQ(ierr);
>
>     PetscDS ds;
>     ierr = DMGetDS(dm, &ds); CHKERRQ(ierr);
>     ierr = PetscDSSetResidual(ds, 0, f0_volum, f1_volum); CHKERRQ(ierr);
>     ierr = PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, g3_jacobia); CHKERRQ(ierr);
>
>     DMLabel label;
>     // 1. Intentem buscar el nom que has posat tu
>     ierr = DMGetLabel(dm, "Frontera", &label); CHKERRQ(ierr);
>     if (label && rank == 0) PetscPrintf(PETSC_COMM_WORLD, "--> Trobat per nom: 'Frontera'\n");
>
>     // 2. Si no, usem el marker estàndard de PETSc
>     if (!label) {
>         ierr = DMGetLabel(dm, "marker", &label); CHKERRQ(ierr);
>         if (label && rank == 0) PetscPrintf(PETSC_COMM_WORLD, "--> Trobat per nom genèric: 'marker'\n");
>     }
>     if (!label) { ierr = DMGetLabel(dm, "Face Sets", &label); CHKERRQ(ierr); }
>
>     // MODIFICACIÓ DE SEGURETAT: Apliquem a l'ID 1 i a l'ID 2 simultàniament
>     // Si Gmsh o PETSc han mogut l'ID de la superfície del 1 al 2 durant la conversió, els cobrim tots dos.
>     PetscInt numIds = 2;
>     PetscInt ids[2] = {1, 2};
>
>     if (label) {
>         ierr = PetscDSAddBoundary(ds, DM_BC_ESSENTIAL, "ContornExterior", label,
>                                   numIds, ids, 0, 0, NULL,
>                                   (PetscVoidFn *)CondicioContornDirichlet, NULL, NULL, NULL);
>         CHKERRQ(ierr);
>     } else {
>         PetscPrintf(PETSC_COMM_WORLD, "ALERTA: No s'ha trobat cap etiqueta de contorn!\n");
>     }
>
>     // ====================================================================
>     // [Pas 4] ESTRATÈGIA EX03 SENSE INTERFERÈNCIES DE LUA
>     // ====================================================================
>     DM dmAux;
>     PetscFE fe_aux;
>     Vec vectorTemporalLua, vectorResultatsFinal;
>
>     ierr = DMClone(dm, &dmAux); CHKERRQ(ierr);
>     ierr = PetscFECreateLagrange(PETSC_COMM_WORLD, 3, 6, PETSC_TRUE, ordre_element, PETSC_DETERMINE, &fe_aux); CHKERRQ(ierr);
>     ierr = DMSetField(dmAux, 0, NULL, (PetscObject)fe_aux); CHKERRQ(ierr);
>     ierr = DMCreateDS(dmAux); CHKERRQ(ierr);
>
>     ierr = DMCreateLocalVector(dmAux, &vectorTemporalLua); CHKERRQ(ierr);
>
>     PetscErrorCode (*funcs[1])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *);
>     void           *ctxs[1];
>     funcs[0] = EvaluaCoeficientsLua;
>     ctxs[0]  = L;
>
>     ierr = DMProjectFunctionLocal(dmAux, 0.0, funcs, ctxs, INSERT_VALUES, vectorTemporalLua); CHKERRQ(ierr);
>
>     // Tanquem LUA immediatament, exactament com feies a l'ex03 per no embrutar la memòria
>     lua_gc(L, LUA_GCCOLLECT, 0);
>     lua_close(L);
>
>     // Dupliquem per assegurar-nos un vector completament net i homogeni de PETSc
>     ierr = DMCreateLocalVector(dmAux, &vectorResultatsFinal); CHKERRQ(ierr);
>     ierr = VecCopy(vectorTemporalLua, vectorResultatsFinal); CHKERRQ(ierr);
>     ierr = VecDestroy(&vectorTemporalLua); CHKERRQ(ierr);
>
>     ierr = DMSetAuxiliaryVec(dm, NULL, 0, 0, vectorResultatsFinal); CHKERRQ(ierr);
>
>     // [Pas 5] Creem el vector solució global
>     Vec u_solucio;
>     ierr = DMCreateGlobalVector(dm, &u_solucio); CHKERRQ(ierr);
>     ierr = VecZeroEntries(u_solucio); CHKERRQ(ierr);
>
>     // ====================================================================
>     // [Pas 6] CONFIGURACIÓ DE SNES (EL MOTOR CORRECTE PER A DMPLEX FEM)
>     // ====================================================================
>     SNES snes;
>     ierr = SNESCreate(PETSC_COMM_WORLD, &snes); CHKERRQ(ierr);
>     ierr = SNESSetDM(snes, dm); CHKERRQ(ierr);
>
>     // Establir les funcions de DMPlex per al residu i jacobià reals
>     ierr = DMSNESSetFunctionLocal(dm, (PetscErrorCode (*)(DM, Vec, Vec, void *))DMPlexSNESComputeResidualFEM, NULL); CHKERRQ(ierr);
>     ierr = DMSNESSetJacobianLocal(dm, (PetscErrorCode (*)(DM, Vec, Mat, Mat, void *))DMPlexSNESComputeJacobianFEM, NULL); CHKERRQ(ierr);
>
>     ierr = SNESSetFromOptions(snes); CHKERRQ(ierr);
>     // Forcem el solver a comportar-se com un KSP lineal pur
>     ierr = SNESSetType(snes, SNESKSPONLY); CHKERRQ(ierr);
>
>     //-----------------------------------------------------------------
>     // ORDENAT CORRECTAMENT: Declarar, extreure i llavors configurar
>     //-----------------------------------------------------------------
>     KSP ksp; // 1. Declarem la variable
>     ierr = SNESGetKSP(snes, &ksp); CHKERRQ(ierr); // 2. L'extraiem del SNES
>     ierr = KSPSetType(ksp, KSPGMRES); CHKERRQ(ierr); // 3. Configurem el tipus (GMRES)
>     //-----------------------------------------------------------------
>
>     // Executem la resolució paral·lela
>     ierr = SNESSolve(snes, NULL, u_solucio); CHKERRQ(ierr);
>
>     // ===========================================================
>     // PAS 7: ESCRIPTURA NATIVA EN FORMAT VTK (.vtu) - NET DEFINITIU
>     // ===========================================================
>     PetscViewer viewer_vtu;
>     PetscSection section;
>
>     // 1. Creem el viewer en format VTK pur
>     ierr = PetscViewerCreate(PETSC_COMM_WORLD, &viewer_vtu); CHKERRQ(ierr);
>     ierr = PetscViewerSetType(viewer_vtu, PETSCVIEWERVTK); CHKERRQ(ierr);
>
>     // 2. Configurem el fitxer de sortida
>     ierr = PetscViewerFileSetMode(viewer_vtu, FILE_MODE_WRITE); CHKERRQ(ierr);
>     ierr = PetscViewerFileSetName(viewer_vtu, "solucio_torus.vtu"); CHKERRQ(ierr);
>
>     // 3. LA MÀGIA: Definim el nom del camp net a la secció
>     ierr = DMGetLocalSection(dm, &section); CHKERRQ(ierr);
>     if (section) {
>         ierr = PetscSectionSetFieldName(section, 0, "Solucio"); CHKERRQ(ierr);
>     }
>
>     // 4. EL TRUC: No li donem el mateix nom al vector (deixem-lo buit o genèric)
>     // d'aquesta manera evitem la duplicació "SolucioSolucio"
>     ierr = PetscObjectSetName((PetscObject)u_solucio, ""); CHKERRQ(ierr);
>
>     // 5. Escriptura del vector interpolat pels nodes de la malla
>     ierr = VecView(u_solucio, viewer_vtu); CHKERRQ(ierr);
>
>     // 6. Destruïm el viewer
>     ierr = PetscViewerDestroy(&viewer_vtu); CHKERRQ(ierr);
>
>     // ====================================================================
>     // [Pas 8] ESTADÍSTIQUES FINALS
>     // ====================================================================
>     PetscInt its;
>     SNESConvergedReason reason;
>     ierr = SNESGetIterationNumber(snes, &its); CHKERRQ(ierr);
>     ierr = SNESGetConvergedReason(snes, &reason); CHKERRQ(ierr);
>
>     PetscInt n_equacions;
>     ierr = VecGetSize(u_solucio, &n_equacions); CHKERRQ(ierr);
>
>     if (rank == 0) {
>         PetscPrintf(PETSC_COMM_WORLD, "===========================================================\n");
>         PetscPrintf(PETSC_COMM_WORLD, " RESOLUCIÓ PARAL·LELA DE L'EQUACIÓ DEL TÒRUS AMB ÈXIT\n");
>         PetscPrintf(PETSC_COMM_WORLD, " Graus de llibertat totals a la malla: %d\n", n_equacions);
>         PetscPrintf(PETSC_COMM_WORLD, " Raó de convergència del Solver (Reason ID): %d\n", reason);
>         PetscPrintf(PETSC_COMM_WORLD, " Iteracions realitzades: %d\n", its);
>         PetscPrintf(PETSC_COMM_WORLD, "===========================================================\n");
>
>         PetscPrintf(PETSC_COMM_WORLD, "===========================================================\n");
>         PetscPrintf(PETSC_COMM_WORLD, " Generat el fitxer pur 'solucio_torus.vtu'\n");
>         PetscPrintf(PETSC_COMM_WORLD, "===========================================================\n");
>     }
>     // Alliberament final impecable
>     ierr = SNESDestroy(&snes); CHKERRQ(ierr);
>     ierr = VecDestroy(&u_solucio); CHKERRQ(ierr);
>     ierr = VecDestroy(&vectorResultatsFinal); CHKERRQ(ierr);
>     ierr = DMDestroy(&dmAux); CHKERRQ(ierr);
>     ierr = PetscFEDestroy(&fe_u); CHKERRQ(ierr);
>     ierr = PetscFEDestroy(&fe_aux); CHKERRQ(ierr);
>     ierr = DMDestroy(&dm);
>     ierr = PetscFinalize();
>     return ierr;
> }
> function a(x,y,z)
>     return 1.0   -- Sempre serà >= 1.0, mai zero!
> end
>
> function b1(x,y,z) return 0.0 end -- Un transport molt suau
> function b2(x,y,z) return 0.0 end
> function b3(x,y,z) return 0.0 end
>
> function c(x,y,z)
>     return 0.0               -- Reacció amortidora
> end
>
> function f(x,y,z)
>     return 1.0*z
> end
>
> function fem(x,y,z)
>     local r = {}
>     r["a"] = a(x,y,z)
>     r["b1"] = b1(x,y,z)
>     r["b2"] = b2(x,y,z)
>     r["b3"] = b3(x,y,z)
>     r["c"] = c(x,y,z)
>     r["f"] = f(x,y,z)
>     return r
> end
>
> function funcio_contorn(x,y,z)
>     return 100*z
> end
>
>
>

-- 
What most experimenters take for granted before they begin their
experiments is infinitely more interesting than any results to which their
experiments lead.
-- Norbert Wiener

https://urldefense.us/v3/__https://www.cse.buffalo.edu/*knepley/__;fg!!G_uCfscf7eWS!ZF-nNJ74-l_81-p_aqRGdF80LcRs5UL2FUZQhP9G6s00w8eb4aEoXR6uR6fCmGTUF40LQn5VCbgi7zfrdc__$  <https://urldefense.us/v3/__http://www.cse.buffalo.edu/*knepley/__;fg!!G_uCfscf7eWS!ZF-nNJ74-l_81-p_aqRGdF80LcRs5UL2FUZQhP9G6s00w8eb4aEoXR6uR6fCmGTUF40LQn5VCbgi7w2oaDRC$ >
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20260627/547a83be/attachment-0001.html>


More information about the petsc-users mailing list